Note on this code:

R version 3.5.1 (2018-07-02) Platform: x86_64-apple-darwin15.6.0 (64-bit) Running under: macOS Sierra 10.12.6

Code written by Sara D. Williams

Resistance Results Visualization

The following code chunk is used to make Figure 3.

bleachmodel<-read.csv("Resistance.csv", header=T) #compiled results for Resistance from Bleaching model, see Metadata 2 for more information.
summary(bleachmodel)
       X                   Spatial.Scale       R               R_std        
 Min.   : 1.00   Caribbean        : 5    Min.   :0.09428   Min.   :0.00000  
 1st Qu.:18.25   Central Caribbean: 5    1st Qu.:0.19074   1st Qu.:0.01897  
 Median :35.50   Central Pacific  : 5    Median :0.25842   Median :0.02477  
 Mean   :35.50   Eastern Caribbean: 5    Mean   :0.34151   Mean   :0.02941  
 3rd Qu.:52.75   Eastern Pacific  : 5    3rd Qu.:0.50396   3rd Qu.:0.03397  
 Max.   :70.00   Global           : 5    Max.   :0.88822   Max.   :0.10159  
                 (Other)          :40                                       
                                 Simulation   Group       statlab  
 Network                              :14   Carib:15   A      : 7  
 Random Bipartite Degree Conserved    :14   Ind  :15   D      : 7  
 Random Bipartite Not-Degree Conserved:14   Main :20   C      : 6  
 Random Tolerances                    :14   Pac  :20   E      : 6  
 Shuffled Tolerances                  :14              I      : 6  
                                                       F      : 5  
                                                       (Other):33  
theme_set(theme_grey(base_size = 28)) 
#reorder simulations
bleachmodel$Simulation<-factor(bleachmodel$Simulation,levels=c("Network","Shuffled Tolerances","Random Tolerances","Random Bipartite Degree Conserved","Random Bipartite Not-Degree Conserved"))
#plot the global and ocean-basins
Main_oceans<-bleachmodel %>%
  filter(Group=='Main')
#reorder x axis
Main_oceans$Spatial.Scale<-factor(Main_oceans$Spatial.Scale,levels=c("Global","Pacific","Indian","Caribbean"))
main<-ggplot( Main_oceans, aes(x=as.factor(Spatial.Scale), y=R,fill=Simulation)) +
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=R-R_std, ymax=R+R_std), width=.2,position=position_dodge(.9))+
  scale_fill_brewer(palette="BuGn")+
  coord_cartesian(ylim=c(0,1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  xlab("Global and Oceans")+
  ylab("Resistance")+
  #labs(x="Global and Oceans",y="Resistance",size=10)+
  geom_text(aes( label=statlab,y=R+R_std+0.1),position = position_dodge(1),vjust =0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
#caribbean subregions
carib<-bleachmodel %>%
  filter(Group=='Carib')
c<-ggplot( carib, aes(x=as.factor(Spatial.Scale), y=R, fill=Simulation)) +
  geom_bar(position=position_dodge(), stat="identity",colour='black') +
  geom_errorbar(aes(ymin=R-R_std, ymax=R+R_std), width=.2,position=position_dodge(.9))+
  scale_fill_brewer(palette="BuGn")+coord_cartesian(ylim=c(0,1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="Caribbean Regions",y=" ")+
  geom_text(aes( label=statlab,y=R+R_std+0.1),position = position_dodge(1),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
#Pacific subregions
pac<-bleachmodel %>%
  filter(Group=='Pac')
p<-ggplot( pac, aes(x=as.factor(Spatial.Scale), y=R, fill=Simulation)) +
  geom_bar(position=position_dodge(), stat="identity", colour='black') +
  geom_errorbar(aes(ymin=R-R_std, ymax=R+R_std), width=.2,position=position_dodge(.9))+
  scale_fill_brewer(palette="BuGn")+coord_cartesian(ylim=c(0,1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="Pacific Regions",y=" ")+
  geom_text(aes( label=statlab,y=R+R_std+0.1),position = position_dodge(1),vjust=0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
#Indian subregions
ind<-bleachmodel %>%
  filter(Group=='Ind')
i<-ggplot( ind, aes(x=as.factor(Spatial.Scale), y=R, fill=Simulation)) +
  geom_bar(position=position_dodge(), stat="identity", colour='black') +
  geom_errorbar(aes(ymin=R-R_std, ymax=R+R_std), width=.2,position=position_dodge(.9))+
  scale_fill_brewer(palette="BuGn")+coord_cartesian(ylim=c(0,1))+theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="Indian Regions",y="Resistance")+
  geom_text(aes( label=statlab,y=R+R_std+0.1),position = position_dodge(1),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
#Put them all in one plot
ggarrange(main, p, i, c, ncol=2, nrow=2, common.legend = TRUE, legend="bottom")

ggsave("figure3.jpg", plot = last_plot(), device = NULL, path = NULL,scale = 1, width = NA, height = NA, units = c("in"),dpi = 600)
Saving 24 x 16 in image

Robustness

The following code chunk is used to make Figure 4 E-H.

robustness<-read.csv("Robustness.csv") #results of robustness analyses, see metadata 2 for more info
summary(robustness)
    network         mean              std                   model          removed   
 C      : 30   Min.   :0.02041   Min.   :0.000000   bleach     : 42   both     : 56  
 cc     : 30   1st Qu.:0.53709   1st Qu.:0.008193   Degree_high: 42   hosts    : 56  
 cp     : 30   Median :0.64939   Median :0.027461   Degree_low : 42   links    :252  
 ec     : 30   Mean   :0.61124   Mean   :0.037324   LT_BH      : 42   symbionts: 56  
 ep     : 30   3rd Qu.:0.71870   3rd Qu.:0.054356   LT_BL      : 42                  
 G      : 30   Max.   :1.00000   Max.   :0.220333   LT_HL      : 42                  
 (Other):240                                        (Other)    :168                  
   type      R50_who       group2      group        statlab     connectance     
 link:252   both :140   carib :120   carib: 90          :366   Min.   :0.01000  
 node:168   hosts:140   Global: 30   ind  : 90   A      :  7   1st Qu.:0.03700  
            symbs:140   ind   :120   Main :120   B      :  7   Median :0.06650  
                        pac   :150   pac  :120   C      :  7   Mean   :0.07071  
                                                 D      :  6   3rd Qu.:0.08500  
                                                 E      :  6   Max.   :0.23600  
                                                 (Other): 21                    
     hosts         symbionts          links       
 Min.   : 14.0   Min.   : 13.00   Min.   :  43.0  
 1st Qu.: 31.0   1st Qu.: 29.00   1st Qu.:  84.0  
 Median : 83.5   Median : 40.50   Median : 209.5  
 Mean   :144.4   Mean   : 63.21   Mean   : 358.4  
 3rd Qu.:157.0   3rd Qu.: 74.00   3rd Qu.: 404.0  
 Max.   :685.0   Max.   :250.00   Max.   :1697.0  
                                                  
#get rid of the removal models that were tested but not used
data2<-robustness %>%
    filter(model!="LT_BH", model!="LT_HH",model!="LT_SH",model!="Tolerance_high")
  
Global_tot<-data2%>%
  filter(network=="G",removed!="hosts",removed!="symbionts",R50_who=="both")
Global_tot$removed<-factor(Global_tot$removed,levels=c("links"="links","nodes"="both"))
  
global<-ggplot( Global_tot, aes(x=as.factor(model), y=mean,fill=removed))
g_total<-global+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="Robustness, R50")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low","Degree_low","Degree_high"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
Pacific_tot<-data2%>%
  filter(network=="P",removed!="hosts",removed!="symbionts",R50_who=="both")
Pacific_tot$removed<-factor(Pacific_tot$removed,levels=c("links"="links","nodes"="both"))
  
Pacific<-ggplot( Pacific_tot, aes(x=as.factor(model), y=mean,fill=removed))
p_total<-Pacific+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low","Degree_low","Degree_high"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
Carib_tot<-data2%>%
  filter(network=="C",removed!="hosts",removed!="symbionts",R50_who=="both")
Carib_tot$removed<-factor(Carib_tot$removed,levels=c("links"="links","nodes"="both"))
Carib<-ggplot( Carib_tot, aes(x=as.factor(model), y=mean,fill=removed))
c_total<-Carib+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low","Degree_low","Degree_high"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
Ind_tot<-data2%>%
  filter(network=="I",removed!="hosts",removed!="symbionts",R50_who=="both")
Ind_tot$removed<-factor(Carib_tot$removed,levels=c("links"="links","nodes"="both"))
Ind<-ggplot( Ind_tot, aes(x=as.factor(model), y=mean,fill=removed))
i_total<-Ind+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low","Degree_low","Degree_high"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
#Put them all in one plot
ggarrange(g_total,p_total,i_total,c_total, ncol=4, nrow=1, common.legend = FALSE, legend=NULL)

ggsave("figure4etof.jpg", plot = last_plot(), device = NULL, path = NULL,scale = 1, width = NA, height = NA, units = c("in"),dpi = 600)
Saving 24 x 16 in image

The following code chunk is used to make Appendix S2, Figure S1 D-F.

rr

myplot<-function(data2,N){ #data2=robustness results, N=network to plot
  data2<-data2 %>%
    filter(model!=\LT_BH\, model!=\LT_HH\,model!=\LT_SH\,model!=\Tolerance_high\)
  
  Global_tot<-data2%>%
    filter(network==N,removed!=\hosts\,removed!=\symbionts\,R50_who==\both\)
  Global_tot$removed<-factor(Global_tot$removed,levels=c(\links\,\both\,\hosts\,\symbionts\))
  
  global<-ggplot( Global_tot, aes(x=as.factor(model), y=mean,fill=removed))
  g_total<-global+
    geom_bar(position=position_dodge(),stat=\identity\,colour='black',mapping=aes(col=\red\)) +
    geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
    scale_fill_manual(values=c(\links\ = \#7fc97f\, \both\ = \#99d8c9\, \hosts\ = \#a6cee3\,\symbionts\=\#ffff99\), 
                      drop = FALSE)+
    
    #ylim(0,1)+
    scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
    theme(panel.background = element_blank())+ 
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
          panel.background = element_blank(), axis.line = element_line(colour = \black\))+
    labs(x=\\,y=\Total Robustness\)+
    theme(axis.text.x = element_text(angle = 70, hjust = 1))+
    scale_x_discrete(limits=c(\Random_link\,\bleach\,\LT_BL\,\LT_HL\,\LT_SL\,\Random_node\,\Tolerance_low\,\Degree_low\,\Degree_high\),
                     labels=c(\Random_link\=\Random\,\bleach\=\Bleaching\,\Tolerance_low\=\Susceptible\,\Tolerance_high\=\High Tolerance\,\Degree_high\= \High Degree\,\Degree_low\=\Low Degree\,\Random_node\=\Random Node\,\LT_BH\=\High Avg. Link Tolerance\,\LT_BL\=\Susceptible\,\LT_HH\=\High Host Link Tolerance\,\LT_HL\=\Host Susceptible\,\LT_SH\=\High Symbiont Link Tolerance\,\LT_SL\=\Symbiont Susceptible\))+
    geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0)
  
  Global_h<-data2%>%
    filter(network==N,removed!=\hosts\,removed!=\both\,R50_who==\hosts\)
  Global_h$removed<-factor(Global_h$removed,levels=c(\links\,\both\,\hosts\,\symbionts\))
  global_h<-ggplot( Global_h, aes(x=as.factor(model), y=mean,fill=removed))
  g_hosts<-global_h+
    geom_bar(position=position_dodge(),stat=\identity\,colour='black',mapping=aes(col=\red\)) +
    geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
    scale_fill_manual(values=c(\links\ = \#7fc97f\, \both\ = \#99d8c9\, \hosts\ = \#a6cee3\,\symbionts\=\#ffff99\), 
                      drop = FALSE)+
    scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
    theme(panel.background = element_blank())+ 
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
          panel.background = element_blank(), axis.line = element_line(colour = \black\))+
    labs(x=\\,y=\Host Robustness\)+
    theme(axis.text.x = element_text(angle = 70, hjust = 1))+
    scale_x_discrete(limits=c(\Random_link\,\bleach\,\LT_BL\,\LT_HL\,\LT_SL\,\Random_node\,\Tolerance_low\,\Degree_low\,\Degree_high\),
                     labels=c(\Random_link\=\Random\,\bleach\=\Bleaching\,\Tolerance_low\=\Susceptible\,\Tolerance_high\=\High Tolerance\,\Degree_high\= \High Degree\,\Degree_low\=\Low Degree\,\Random_node\=\Random Node\,\LT_BH\=\High Avg. Link Tolerance\,\LT_BL\=\Susceptible\,\LT_HH\=\High Host Link Tolerance\,\LT_HL\=\Host Susceptible\,\LT_SH\=\High Symbiont Link Tolerance\,\LT_SL\=\Symbiont Susceptible\))+
    geom_text(aes( label=statlab,y=mean+std+0.03),position = position_dodge(0.9),vjust =0)
  
  Global_s<-data2%>%
    filter(network==N,removed!=\symbionts\,removed!=\both\,R50_who==\symbs\)
  Global_s$removed<-factor(Global_s$removed,levels=c(\links\,\both\,\hosts\,\symbionts\))
  global_s<-ggplot( Global_s, aes(x=as.factor(model), y=mean,fill=removed))
  g_symbs<-global_s+
    geom_bar(position=position_dodge(),stat=\identity\,colour='black',mapping=aes(col=\red\)) +
    geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
    scale_fill_manual(values=c(\links\ = \#7fc97f\, \both\ = \#99d8c9\, \hosts\ = \#a6cee3\,\symbionts\=\#ffff99\), 
                      drop = FALSE)+
    scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
    theme(panel.background = element_blank())+ 
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
          panel.background = element_blank(), axis.line = element_line(colour = \black\))+
    labs(x=\\,y=\Symbiont Robustness\)+
    theme(axis.text.x = element_text(angle = 70, hjust = 1))+
    scale_x_discrete(limits=c(\Random_link\,\bleach\,\LT_BL\,\LT_HL\,\LT_SL\,\Random_node\,\Tolerance_low\,\Degree_low\,\Degree_high\),
                     labels=c(\Random_link\=\Random\,\bleach\=\Bleaching\,\Tolerance_low\=\Susceptible\,\Tolerance_high\=\High Tolerance\,\Degree_high\= \High Degree\,\Degree_low\=\Low Degree\,\Random_node\=\Random Node\,\LT_BH\=\High Avg. Link Tolerance\,\LT_BL\=\Susceptible\,\LT_HH\=\High Host Link Tolerance\,\LT_HL\=\Host Susceptible\,\LT_SH\=\High Symbiont Link Tolerance\,\LT_SL\=\Symbiont Susceptible\))+
    geom_text(aes( label=statlab,y=mean+std+0.03),position = position_dodge(0.9),vjust =0)
  
  theme_set(theme_grey(base_size = 14)) 
  p<-ggarrange(g_total,g_hosts,g_symbs, ncol=3, nrow=1, common.legend = TRUE, legend=\bottom\)
  return(p)
}
myplot(robustness,\G\)

Randomization Tests

See Appendix S2 for description. Randomization tests are often called permutation tests, thus I use “permutation” within the code.

rr

mypermutation_twocomp<-function(data,netA,netB,levelA,levelB,nsims){
  #get data
  #levels(data$net_type)<-c(\hsrand_dtemp\, \net_dtemp\, \rand_dtemp\,\rbdc_dtemp\, \rbndc_dtemp\)
  #split data for two levels
  net1 <- data%>%
    filter(net_type==netA)
  net2 <- data%>%
    filter(net_type==netB)
  twocomps<-rbind(net1,net2)
  # initialize test
  combined_resistance <- c(net1$resistance,net2$resistance) #combines resistance values into a vector
  combined_labels <- c(net1$net_type,net2$net_type)#combines network type into a vector
  diff_obs <- mean(net1$resistance) - mean(net2$resistance)
  model <- anova(lm(twocomps$resistance ~ twocomps$net_type)) 
  obt.F <- model$\F value\[1]     # Our obtained F  statistic
  obt.p <- model$\Pr(>F)\[1]
  
  # permutation test
  diffs <- rep(NA, nsims)
  fstats<-rep(NA,nsims)
  for (i in 1:nsims) {
    #shuffle the labels
    shuffled_labels <- sample(combined_labels, replace = FALSE)
    twocomps$shuffled_labels<-shuffled_labels
    #shuffle the resistances
    shuffled_resistance<-sample(combined_resistance, replace = FALSE)
    twocomps$shuffled_resistance<-shuffled_resistance
    #get the differences in the means of the shuffled groups
    diffs[i] <- mean(shuffled_resistance[shuffled_labels == levelA]) -  mean(shuffled_resistance[shuffled_labels == levelB])
    #run a new anova
    newmodel <- anova(lm(twocomps$shuffled_resistance ~ twocomps$shuffled_labels)) 
    fstats[i] <- newmodel$\F value\[1]     # get a new F  statistic
  }
  #calculate the two-sided p-value
  # p-value = (number of more extreme differences than diff_obs)/nsims
  pval_diffs<-length(diffs[abs(diffs) >= abs(diff_obs)])/nsims
  pval_fstatdifs<-(length(fstats[abs(fstats) > abs(obt.F)])+1)/(1+nsims)
  return(c(diff_obs,obt.p,obt.F,pval_diffs,pval_fstatdifs))
}
resistance_perms<-function(file,nsims){
  #get data
  resist_data<-read.csv(file)
  #select columns
  selectdata<-resist_data%>%
    select(hsrand_dtemp,net_dtemp,rand_dtemp,rbdc_dtemp,rbndc_dtemp)
  #get into long format
  longdata <- gather(selectdata, key=net_type,value=resistance,factor_key = TRUE)
  #setup storage for permutation results
  resmat<-matrix(NA,nrow=0,ncol=7)
  pvals<-rep()
  #run permutations
  for (j in 1:(length(levels(longdata$net_type))-1)){
    netA<-levels(longdata$net_type)[j]
    for (i in (j+1):length(levels(longdata$net_type))){
      netB<-levels(longdata$net_type)[i]
      levelA<-j
      levelB<-i
      #print(c(netA,netB,levelA,levelB))
      permresults<-mypermutation_twocomp(longdata,netA,netB,levelA,levelB,1000)
      #print(results)
      #pvals<-append(pvals,permresults[5])
      permres<-c(permresults,netA,netB)
      resmat<-rbind(resmat,permres)
  }
}
  all_results<-cbind(resmat,p.adjust(as.numeric(resmat[,5]),\holm\)) #adjust p values using the holm correction
  results<-as.data.frame(all_results)
  colnames(results)<-c(\diff_obs\,\obt.p\,\obt.F\,\pval_diffs\,\pval_fstatdifs\,\net1\,\net2\,\p_adjust_holm\)
  return(results)
}
#TEST
resistance_perms(\TEST_resistance_perms.csv\,1000)
                     diff_obs                obt.p
permres   0.00412371134020573    0.702317494689414
permres.1  -0.436082474226805 6.33757407839271e-88
permres.2  -0.152577319587629 2.49559940772465e-38
permres.3  -0.121649484536083 5.37670669053595e-26
permres.4  -0.440206185567011 3.32885050387969e-86
permres.5  -0.156701030927835 5.16592722639757e-37
permres.6  -0.125773195876289 1.85944491914943e-25
permres.7   0.283505154639176 2.96101092082189e-63
permres.8   0.314432989690722 3.42201761802395e-67
permres.9  0.0309278350515463 0.000594160717217541
                      obt.F pval_diffs
permres   0.146508966043483      0.776
permres.1   1318.0773480663          0
permres.2  268.554789272025          0
permres.3  151.108297535609          0
permres.4  1257.08014938236          0
permres.5  254.297638156382          0
permres.6  146.730745532962          0
permres.7  644.188110026627          0
permres.8  726.876119160036          0
permres.9  12.1964991530209      0.001
                pval_fstatdifs         net1
permres      0.725274725274725 hsrand_dtemp
permres.1 0.000999000999000999 hsrand_dtemp
permres.2 0.000999000999000999 hsrand_dtemp
permres.3 0.000999000999000999 hsrand_dtemp
permres.4 0.000999000999000999    net_dtemp
permres.5 0.000999000999000999    net_dtemp
permres.6 0.000999000999000999    net_dtemp
permres.7 0.000999000999000999   rand_dtemp
permres.8 0.000999000999000999   rand_dtemp
permres.9    0.001998001998002   rbdc_dtemp
                 net2       p_adjust_holm
permres     net_dtemp   0.725274725274725
permres.1  rand_dtemp 0.00999000999000999
permres.2  rbdc_dtemp 0.00999000999000999
permres.3 rbndc_dtemp 0.00999000999000999
permres.4  rand_dtemp 0.00999000999000999
permres.5  rbdc_dtemp 0.00999000999000999
permres.6 rbndc_dtemp 0.00999000999000999
permres.7  rbdc_dtemp 0.00999000999000999
permres.8 rbndc_dtemp 0.00999000999000999
permres.9 rbndc_dtemp 0.00999000999000999

Robustness vs. Connectance

See Appendix S2 for description.

rr

#load data
robustness<-read.csv(\Robustness.csv\)
#check distribution of connectance
plot(density((log(robustness$connectance)))) #It's wonky.

rr

#make it easy to plot removal model of choice vs connectance with a linear fit
my_RClinreg_plot<-function(choice){
  data<-robustness %>%
    filter(model!=\LT_BH\, model!=\LT_HH\,model!=\LT_SH\,model!=\Tolerance_high\,R50_who==\both\,model==choice)
  p<-ggplotRegression(lm(mean ~ connectance, data = data),choice)
  p+geom_point(y=data$mean,x=data$connectance,aes(color=data$group),size=6)
  
}
#run a Kendall's coefficient of rank correlation test on removal model of choice
my_cortest<-function(choice){
  data<-robustness %>%
    filter(model!=\LT_BH\, model!=\LT_HH\,model!=\LT_SH\,model!=\Tolerance_high\,R50_who==\both\,model==choice)
  ct<-cor.test(data$mean,data$connectance,method=\kendall\)
  return(ct)
}
#run for different removal models 
my_RClinreg_plot(\bleach\)

rr

my_cortest(\bleach\) 

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 67, p-value = 0.01928
alternative hypothesis: true tau is not equal to 0
sample estimates:
      tau 
0.4725275 

rr

my_RClinreg_plot(\Random_link\)

rr

my_cortest(\Random_link\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 52, p-value = 0.5183
alternative hypothesis: true tau is not equal to 0
sample estimates:
      tau 
0.1428571 

rr

my_RClinreg_plot(\LT_BL\)

rr

my_cortest(\LT_BL\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 55, p-value = 0.3308
alternative hypothesis: true tau is not equal to 0
sample estimates:
      tau 
0.2087912 

rr

my_RClinreg_plot(\LT_HL\)

rr

my_cortest(\LT_HL\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 56, p-value = 0.2792
alternative hypothesis: true tau is not equal to 0
sample estimates:
      tau 
0.2307692 

rr

my_RClinreg_plot(\LT_SL\)

rr

my_cortest(\LT_SL\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 42, p-value = 0.7472
alternative hypothesis: true tau is not equal to 0
sample estimates:
        tau 
-0.07692308 

rr

my_RClinreg_plot(\Degree_high\)

rr

my_cortest(\Degree_high\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 72, p-value = 0.003025
alternative hypothesis: true tau is not equal to 0
sample estimates:
      tau 
0.5824176 

rr

my_RClinreg_plot(\Degree_low\)

rr

my_cortest(\Degree_low\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 27, p-value = 0.04718
alternative hypothesis: true tau is not equal to 0
sample estimates:
       tau 
-0.4065934 

rr

my_RClinreg_plot(\Random_node\)

rr

my_cortest(\Random_node\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 47, p-value = 0.9145
alternative hypothesis: true tau is not equal to 0
sample estimates:
       tau 
0.03296703 

rr

my_RClinreg_plot(\Tolerance_low\)

rr

my_cortest(\Tolerance_low\)

    Kendall's rank correlation tau

data:  data$mean and data$connectance
T = 56, p-value = 0.2792
alternative hypothesis: true tau is not equal to 0
sample estimates:
      tau 
0.2307692 

Symbiont node thermal tolerances: picking missing tolerances

Code for Appendix S1, Figure S1: Frequency distribution of Symbiodinium thermal tolerance scores adapted from Swain et al. (2017); distribution is colored by tolerance range, red is highly susceptible, orange is medium tolerance, and yellow is high tolerance. Swain et al. (2017) provides a framework for a consensus of Symbiodinium thermotolerance ranks developed from rank-aggregation methods. Their ranking scheme orders Symbiodinium phylotypes from 0-100, but the rank values are not indicative of total magnitude differences in thermotolerance. To determine tolerances of the unlisted symbiont types in our network, rank values were randomly drawn from the high, medium, and low thermal tolerance frequency distributions in the relative proportions of the clades represented in those distributions. Thus, for each simulation of either the bleaching or different removal models described below, the symbiont tolerances varied within a set distribution (Figure 1D).

rr

### Exploring data from Swain et al 2016a ####
data<-read.csv(\SwainSymbsR.csv\)
#frequency distribution --> inset from figure 1 from paper
bins=seq(0,100,by=2)
#split the frequency distribution into 3 subsets defined by swain et al 16
low <- data[which(data$ScoreR_k<=17),]
high <- data[which(data$ScoreR_k>=33),]
middle<- data[which(data$ScoreR_k>17 & data$ScoreR_k<33),]
#High hist
hist(high$ScoreR_k, breaks=bins, col=\yellow\, ylim=c(0,12), xlab=\thermotolerance score\, main=\Frequency Distributions of Thermotolerance Scores\)
#middle hist
hist(middle$ScoreR_k, breaks=bins, col=\orange\, add=T)
#low hist
hist(low$ScoreR_k, breaks=bins, col=\red\, add=T)

Code for fitting the above thermal toelrance distributions distributions

rr

### Fit the Thermotolerance Distributions ####
#first need the mixtools package
if(!(\mixtools\ %in% installed.packages())){install.packages(\mixtools\)}
Warning in install.packages :
  cannot open URL 'https://cran.rstudio.com/bin/macosx/el-capitan/contrib/3.5/PACKAGES.rds': HTTP status was '404 Not Found'
trying URL 'https://cran.rstudio.com/bin/macosx/el-capitan/contrib/3.5/mixtools_1.1.0.tgz'
Content type 'application/x-gzip' length 1413097 bytes (1.3 MB)
==================================================
downloaded 1.3 MB

The downloaded binary packages are in
    /var/folders/9_/h1rwfkm916nc6pcl1dsx6r6h0000gn/T//Rtmpfw2FHQ/downloaded_packages

rr

library(\mixtools\)
mixtools package, version 1.1.0, Released 2017-03-10
This package is based upon work supported by the National Science Foundation under Grant No. SES-0518772.

rr

#Use the expectation Maximization (EM) Approach
em <- normalmixEM(data$ScoreR_k, arbvar = TRUE,epsilon = 1e-03, k = 3)
number of iterations= 8 

rr

# Estimated means
em$mu
[1]  7.993676 34.266710 54.339110

rr

# Estimated standard deviations
em$sigma
[1]  2.531190 17.196483  1.094525

rr

###RESULTS
#> em$mu
#[1]  7.983029 29.408570 51.900339
#> em$sigma
#[1]  2.711480  9.500587 18.006626
#do 10000 simulations ####
runs <- 10000
sims.low <- rnorm(runs,mean=7.983029,sd=2.711480)
sims.middle <-rnorm(runs,mean=29.408570,sd=9.500587)
sims.high<-rnorm(runs,mean=51.900339,sd=18.006626)
#High hist
hist(sims.high, col=\yellow\)
#middle hist
hist(sims.middle, col=\orange\, add=T)
#low hist
hist(sims.low, col=\red\, add=T)

Code for setting up for toelrance function

rr

#VALUES THAT ARE NEEDED #### 
##These are just the numbers of symbs from each clade in each freq level from Swain
swain_A<-8
swain_B<-8
swain_C<-71
swain_D<-19
swain_E<-1
swain_F<-3
low_A<-1
middle_A<-3
high_A<-4
prob_low_A<-low_A/swain_A
prob_middle_A<-middle_A/swain_A
prob_high_A<-high_A/swain_A
low_B<-3
middle_B<-4
high_B<-1
prob_low_B<-low_B/swain_B
prob_middle_B<-middle_B/swain_B
prob_high_B<-high_B/swain_B
low_C<-24
middle_C<-19
high_C<-28
prob_low_C<-low_C/swain_C
prob_middle_C<-middle_C/swain_C
prob_high_C<-high_C/swain_C
low_D<-3
middle_D<-4
high_D<-12
prob_low_D<-low_D/swain_D
prob_middle_D<-middle_D/swain_D
prob_high_D<-high_D/swain_D
low_E<-1
prob_low_E<-1
prob_middle_E<-0
prob_high_E<-0
high_F<-3
prob_low_F<-0
prob_middle_F<-0
prob_high_F<-1
#OK so these are the number of symbs in each clade that dont have tolerances 
net_A<-6
net_B<-13
net_C<-160
net_D<-6
net_E<-0
net_F<-0

Function for getting the tolerances

rr

get_tols<-function(size,lowprob,midprob,highprob,runs,sims.low,sims.middle,sims.high){
  #make a sample distribution where 1 corresponds to the low thermaltolerance,
  # 2 is the medium and 3 is high. 1:3 are put into the sample distribution 
  #based on the probabilities in the function input that are clade specific
  sampledistr<-sample(x = 1:3, size = size, prob = c(lowprob, midprob, highprob), replace=TRUE)
  tolerance<-numeric(length=size)
  for (i in 1:size) { #for each number in the sampledistr do:
    if (sampledistr[i]==1){
      tolerance[i]<-sample(x=sims.low,size=1) #pull from low
    }
    else if (sampledistr[i]==2){ #pull from middle
      tolerance[i]<-sample(x=sims.middle,size=1)
    }
    else 
      tolerance[i]<-sample(x=sims.high,size=1) #pull from high
  }
  tolerance<-sqrt(tolerance)/10 #take the sqrt because swain's tolerances are not indicative of magnitude and then divide by 10 to get a number from 0-1
  return(tolerance)
}

Make 100 simulations worth of tolerance files

rr

trials=1 #actually did 100, but don't want to make a ton of new files, so here is 1 example file.
lst=seq(1:trials)
for(i in seq_along(lst)){
  Ctols<-get_tols(net_C,prob_low_C,prob_middle_C,prob_high_C,10000,sims.low,sims.middle,sims.high)
  Atols<-get_tols(net_A,prob_low_A,prob_middle_A,prob_high_A,10000,sims.low,sims.middle,sims.high)
  Btols<-get_tols(net_B,prob_low_B,prob_middle_B,prob_high_B,10000,sims.low,sims.middle,sims.high)
  Dtols<-get_tols(net_D,prob_low_D,prob_middle_D,prob_high_D,10000,sims.low,sims.middle,sims.high)
  Ctols<-as.data.frame(Ctols)
  Atols<-as.data.frame(Atols)
  Btols<-as.data.frame(Btols)
  Dtols<-as.data.frame(Dtols)
  colnames(Ctols) <- c(\tolerance\)
  colnames(Btols) <- c(\tolerance\)
  colnames(Dtols) <- c(\tolerance\)
  colnames(Atols) <- c(\tolerance\)
  newscores<-rbind(Atols,Btols,Ctols,Dtols)
  name<-paste('trial',i,\.csv\,sep=\\)
  
  write.csv(newscores,name,row.names=FALSE)
}

Now for the shuffled tolerances:

rr

# Now get the toleranes for the Shuffled Symbionts/ Shuffled Random null model ####
#for the random set of tolerances where they are all pulled equally from the 3 distributions
runs=10000
sims.low <- rnorm(runs,mean=7.983029,sd=2.711480)
sims.low<-subset(sims.low,sims.low>=0)
sims.middle <-rnorm(runs,mean=29.408570,sd=9.500587)
sims.middle<-subset(sims.middle,sims.middle>=0)
sims.high<-rnorm(runs,mean=51.900339,sd=18.006626) 
sims.high<-subset(sims.high,sims.high<=100)
sims.high<-subset(sims.high,sims.high>=0)
#so the following function does what the old one did but also specifies
#if using probabilies determined from data or if pulling all values from 
#the distributions with the same probability (1/3)
allthedata<-function(probability,trials,sims.low,sims.middle,sims.high,net_A,net_B,net_C,net_D){
  if (probability==1){
    swain_A<-8
    swain_B<-8
    swain_C<-71
    swain_D<-19
    swain_E<-1
    swain_F<-3
    
    low_A<-1
    middle_A<-3
    high_A<-4
    prob_low_A<-low_A/swain_A
    prob_middle_A<-middle_A/swain_A
    prob_high_A<-high_A/swain_A
    
    low_B<-3
    middle_B<-4
    high_B<-1
    prob_low_B<-low_B/swain_B
    prob_middle_B<-middle_B/swain_B
    prob_high_B<-high_B/swain_B
    
    low_C<-24
    middle_C<-19
    high_C<-28
    prob_low_C<-low_C/swain_C
    prob_middle_C<-middle_C/swain_C
    prob_high_C<-high_C/swain_C
    
    low_D<-3
    middle_D<-4
    high_D<-12
    prob_low_D<-low_D/swain_D
    prob_middle_D<-middle_D/swain_D
    prob_high_D<-high_D/swain_D
    
    low_E<-1
    prob_low_E<-1
    prob_middle_E<-0
    prob_high_E<-0
    
    high_F<-3
    prob_low_F<-0
    prob_middle_F<-0
    prob_high_F<-1
    
  }
  else
    prob_low_C=prob_middle_C=prob_high_C=prob_low_A=prob_middle_A=prob_high_A=prob_low_B=prob_middle_B=prob_high_B=prob_low_D=prob_middle_D=prob_high_D=(1/3)
  
  #net_A<-8
  #net_B<-18
  #net_C<-177
  #net_D<-7
  #net_E<-0
  #net_F<-0
  lst=seq(1:trials)
  for(i in seq_along(lst)){
    Ctols<-get_tols(net_C,prob_low_C,prob_middle_C,prob_high_C,10000,sims.low,sims.middle,sims.high)
    Atols<-get_tols(net_A,prob_low_A,prob_middle_A,prob_high_A,10000,sims.low,sims.middle,sims.high)
    Btols<-get_tols(net_B,prob_low_B,prob_middle_B,prob_high_B,10000,sims.low,sims.middle,sims.high)
    Dtols<-get_tols(net_D,prob_low_D,prob_middle_D,prob_high_D,10000,sims.low,sims.middle,sims.high)
    Ctols<-as.data.frame(Ctols)
    Atols<-as.data.frame(Atols)
    Btols<-as.data.frame(Btols)
    Dtols<-as.data.frame(Dtols)
    colnames(Ctols) <- c(\tolerance\)
    colnames(Btols) <- c(\tolerance\)
    colnames(Dtols) <- c(\tolerance\)
    colnames(Atols) <- c(\tolerance\)
    newscores<-rbind(Atols,Btols,Ctols,Dtols)
    name<-paste('rtrial',i,\.csv\,sep=\\)
    
    write.csv(newscores,name,row.names=FALSE)
  }
}
#size of the clades in the network
net_A<-10
net_B<-20
net_C<-211
net_D<-9
allthedata(0,1,sims.low,sims.middle,sims.high,net_A,net_B,net_C,net_D)

Revised Figures

Figure 4, now without the degree removal models

#,fig.height=2,fig.width=4.5}
robustness<-read.csv("Robustness.csv") #results of robustness analyses, see metadata 2 for more info
summary(robustness)
    network         mean              std                   model          removed   
 C      : 30   Min.   :0.02041   Min.   :0.000000   bleach     : 42   both     : 56  
 cc     : 30   1st Qu.:0.53709   1st Qu.:0.008193   Degree_high: 42   hosts    : 56  
 cp     : 30   Median :0.64939   Median :0.027461   Degree_low : 42   links    :252  
 ec     : 30   Mean   :0.61124   Mean   :0.037324   LT_BH      : 42   symbionts: 56  
 ep     : 30   3rd Qu.:0.71870   3rd Qu.:0.054356   LT_BL      : 42                  
 G      : 30   Max.   :1.00000   Max.   :0.220333   LT_HL      : 42                  
 (Other):240                                        (Other)    :168                  
   type      R50_who       group2      group        statlab     connectance     
 link:252   both :140   carib :120   carib: 90          :366   Min.   :0.01000  
 node:168   hosts:140   Global: 30   ind  : 90   A      :  7   1st Qu.:0.03700  
            symbs:140   ind   :120   Main :120   B      :  7   Median :0.06650  
                        pac   :150   pac  :120   C      :  7   Mean   :0.07071  
                                                 D      :  6   3rd Qu.:0.08500  
                                                 E      :  6   Max.   :0.23600  
                                                 (Other): 21                    
     hosts         symbionts          links       
 Min.   : 14.0   Min.   : 13.00   Min.   :  43.0  
 1st Qu.: 31.0   1st Qu.: 29.00   1st Qu.:  84.0  
 Median : 83.5   Median : 40.50   Median : 209.5  
 Mean   :144.4   Mean   : 63.21   Mean   : 358.4  
 3rd Qu.:157.0   3rd Qu.: 74.00   3rd Qu.: 404.0  
 Max.   :685.0   Max.   :250.00   Max.   :1697.0  
                                                  
#get rid of the removal models that were tested but not used
data2<-robustness %>%
    filter(model!="LT_BH", model!="LT_HH",model!="LT_SH",model!="Tolerance_high",model!="Degree_high",model!="Degree_low")%>%
  droplevels()
levels(data2$model)
[1] "bleach"        "LT_BL"         "LT_HL"         "LT_SL"         "Random_link"  
[6] "Random_node"   "Tolerance_low"
Global_tot<-data2%>%
  filter(network=="G",removed!="hosts",removed!="symbionts",R50_who=="both")
Global_tot$removed<-factor(Global_tot$removed,levels=c("links"="links","nodes"="both"))
  
global<-ggplot( Global_tot, aes(x=as.factor(model), y=mean,fill=removed))
g_total<-global+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="Robustness, R50")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
Pacific_tot<-data2%>%
  filter(network=="P",removed!="hosts",removed!="symbionts",R50_who=="both")
Pacific_tot$removed<-factor(Pacific_tot$removed,levels=c("links"="links","nodes"="both"))
  
Pacific<-ggplot( Pacific_tot, aes(x=as.factor(model), y=mean,fill=removed))
p_total<-Pacific+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
Carib_tot<-data2%>%
  filter(network=="C",removed!="hosts",removed!="symbionts",R50_who=="both")
Carib_tot$removed<-factor(Carib_tot$removed,levels=c("links"="links","nodes"="both"))
Carib<-ggplot( Carib_tot, aes(x=as.factor(model), y=mean,fill=removed))
c_total<-Carib+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
Ind_tot<-data2%>%
  filter(network=="I",removed!="hosts",removed!="symbionts",R50_who=="both")
Ind_tot$removed<-factor(Carib_tot$removed,levels=c("links"="links","nodes"="both"))
Ind<-ggplot( Ind_tot, aes(x=as.factor(model), y=mean,fill=removed))
i_total<-Ind+
  geom_bar(position=position_dodge(),stat="identity",colour='black',mapping=aes(col="red")) +
  geom_errorbar(aes(ymin=mean-std, ymax=mean+std), width=.2,position=position_dodge(.9))+
  scale_fill_manual(values=c("links" = "#7fc97f", "both" = "#99d8c9", "hosts" = "#a6cee3","symbionts"="#ffff99"), drop = FALSE)+
  #ylim(0,1)+
  scale_y_continuous(limits=c(0,1.05),expand = c(0,0),breaks=seq(0, 1, 0.1))+
  theme(panel.background = element_blank())+ 
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))+
  labs(x="",y="")+
  theme(legend.position="none",axis.text.x = element_text(angle = 70, hjust = 1))+
  scale_x_discrete(limits=c("Random_link","bleach","LT_BL","LT_HL","LT_SL","Random_node","Tolerance_low"),labels=c("Random_link"="Random","bleach"="Bleaching","Tolerance_low"="Susceptible","Tolerance_high"="High Tolerance","Degree_high"= "High Degree","Degree_low"="Low Degree","Random_node"="Random Node","LT_BH"="High Avg. Link Tolerance","LT_BL"="Susceptible","LT_HH"="High Host Link Tolerance","LT_HL"="Host Susceptible","LT_SH"="High Symbiont Link Tolerance","LT_SL"="Symbiont Susceptible"))+
  geom_text(aes( label=statlab,y=mean+std+0.05),position = position_dodge(0.9),vjust = 0,size=8)+theme(
  axis.title.x = element_text(size = 24),
  axis.text.x = element_text(size = 20),
  axis.title.y = element_text(size = 24),
  axis.text.y=element_text(size=20))
#Put them all in one plot
ggarrange(g_total,p_total,i_total,c_total, ncol=4, nrow=1, common.legend = FALSE, legend=NULL)

ggsave("figure4etof.jpg", plot = last_plot(), device = NULL, path = NULL,scale = 1, width = NA, height = NA, units = c("in"),dpi = 600)
Saving 24 x 16 in image
LS0tCnRpdGxlOiAiUmVzaXN0YW5jZSBhbmQgUm9idXN0bmVzcyBWaXN1YWxpemF0aW9ucyBhbmQgU3RhdGlzdGljcyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTgpIAojbG9hZCBwYWNrYWdlcyBuZWVkZWQKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KHZlZ2FuKQpsaWJyYXJ5KGNvaW4pCgpgYGAKIyMjIyBOb3RlIG9uIHRoaXMgY29kZToKUiB2ZXJzaW9uIDMuNS4xICgyMDE4LTA3LTAyKQpQbGF0Zm9ybTogeDg2XzY0LWFwcGxlLWRhcndpbjE1LjYuMCAoNjQtYml0KQpSdW5uaW5nIHVuZGVyOiBtYWNPUyBTaWVycmEgMTAuMTIuNgoKQ29kZSB3cml0dGVuIGJ5IFNhcmEgRC4gV2lsbGlhbXMKCiMjIFJlc2lzdGFuY2UgUmVzdWx0cyBWaXN1YWxpemF0aW9uCgpUaGUgZm9sbG93aW5nIGNvZGUgY2h1bmsgaXMgdXNlZCB0byBtYWtlIEZpZ3VyZSAzLgoKYGBge3J9CmJsZWFjaG1vZGVsPC1yZWFkLmNzdigiUmVzaXN0YW5jZS5jc3YiLCBoZWFkZXI9VCkgI2NvbXBpbGVkIHJlc3VsdHMgZm9yIFJlc2lzdGFuY2UgZnJvbSBCbGVhY2hpbmcgbW9kZWwsIHNlZSBNZXRhZGF0YSAyIGZvciBtb3JlIGluZm9ybWF0aW9uLgpzdW1tYXJ5KGJsZWFjaG1vZGVsKQp0aGVtZV9zZXQodGhlbWVfZ3JleShiYXNlX3NpemUgPSAyOCkpIAojcmVvcmRlciBzaW11bGF0aW9ucwpibGVhY2htb2RlbCRTaW11bGF0aW9uPC1mYWN0b3IoYmxlYWNobW9kZWwkU2ltdWxhdGlvbixsZXZlbHM9YygiTmV0d29yayIsIlNodWZmbGVkIFRvbGVyYW5jZXMiLCJSYW5kb20gVG9sZXJhbmNlcyIsIlJhbmRvbSBCaXBhcnRpdGUgRGVncmVlIENvbnNlcnZlZCIsIlJhbmRvbSBCaXBhcnRpdGUgTm90LURlZ3JlZSBDb25zZXJ2ZWQiKSkKCiNwbG90IHRoZSBnbG9iYWwgYW5kIG9jZWFuLWJhc2lucwpNYWluX29jZWFuczwtYmxlYWNobW9kZWwgJT4lCiAgZmlsdGVyKEdyb3VwPT0nTWFpbicpCiNyZW9yZGVyIHggYXhpcwpNYWluX29jZWFucyRTcGF0aWFsLlNjYWxlPC1mYWN0b3IoTWFpbl9vY2VhbnMkU3BhdGlhbC5TY2FsZSxsZXZlbHM9YygiR2xvYmFsIiwiUGFjaWZpYyIsIkluZGlhbiIsIkNhcmliYmVhbiIpKQptYWluPC1nZ3Bsb3QoIE1haW5fb2NlYW5zLCBhZXMoeD1hcy5mYWN0b3IoU3BhdGlhbC5TY2FsZSksIHk9UixmaWxsPVNpbXVsYXRpb24pKSArCiAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSxzdGF0PSJpZGVudGl0eSIsY29sb3VyPSdibGFjaycsbWFwcGluZz1hZXMoY29sPSJyZWQiKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Ui1SX3N0ZCwgeW1heD1SK1Jfc3RkKSwgd2lkdGg9LjIscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJCdUduIikrCiAgY29vcmRfY2FydGVzaWFuKHlsaW09YygwLDEpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogIHhsYWIoIkdsb2JhbCBhbmQgT2NlYW5zIikrCiAgeWxhYigiUmVzaXN0YW5jZSIpKwogICNsYWJzKHg9Ikdsb2JhbCBhbmQgT2NlYW5zIix5PSJSZXNpc3RhbmNlIixzaXplPTEwKSsKICBnZW9tX3RleHQoYWVzKCBsYWJlbD1zdGF0bGFiLHk9UitSX3N0ZCswLjEpLHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMSksdmp1c3QgPTAsc2l6ZT04KSt0aGVtZSgKICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTIwKSkKCiNjYXJpYmJlYW4gc3VicmVnaW9ucwpjYXJpYjwtYmxlYWNobW9kZWwgJT4lCiAgZmlsdGVyKEdyb3VwPT0nQ2FyaWInKQpjPC1nZ3Bsb3QoIGNhcmliLCBhZXMoeD1hcy5mYWN0b3IoU3BhdGlhbC5TY2FsZSksIHk9UiwgZmlsbD1TaW11bGF0aW9uKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksIHN0YXQ9ImlkZW50aXR5Iixjb2xvdXI9J2JsYWNrJykgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Ui1SX3N0ZCwgeW1heD1SK1Jfc3RkKSwgd2lkdGg9LjIscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJCdUduIikrY29vcmRfY2FydGVzaWFuKHlsaW09YygwLDEpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogIGxhYnMoeD0iQ2FyaWJiZWFuIFJlZ2lvbnMiLHk9IiAiKSsKICBnZW9tX3RleHQoYWVzKCBsYWJlbD1zdGF0bGFiLHk9UitSX3N0ZCswLjEpLHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMSksdmp1c3QgPSAwLHNpemU9OCkrdGhlbWUoCiAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojUGFjaWZpYyBzdWJyZWdpb25zCnBhYzwtYmxlYWNobW9kZWwgJT4lCiAgZmlsdGVyKEdyb3VwPT0nUGFjJykKcDwtZ2dwbG90KCBwYWMsIGFlcyh4PWFzLmZhY3RvcihTcGF0aWFsLlNjYWxlKSwgeT1SLCBmaWxsPVNpbXVsYXRpb24pKSArCiAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSwgc3RhdD0iaWRlbnRpdHkiLCBjb2xvdXI9J2JsYWNrJykgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Ui1SX3N0ZCwgeW1heD1SK1Jfc3RkKSwgd2lkdGg9LjIscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJCdUduIikrY29vcmRfY2FydGVzaWFuKHlsaW09YygwLDEpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogIGxhYnMoeD0iUGFjaWZpYyBSZWdpb25zIix5PSIgIikrCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWw9c3RhdGxhYix5PVIrUl9zdGQrMC4xKSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDEpLHZqdXN0PTAsc2l6ZT04KSt0aGVtZSgKICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTIwKSkKCiNJbmRpYW4gc3VicmVnaW9ucwppbmQ8LWJsZWFjaG1vZGVsICU+JQogIGZpbHRlcihHcm91cD09J0luZCcpCmk8LWdncGxvdCggaW5kLCBhZXMoeD1hcy5mYWN0b3IoU3BhdGlhbC5TY2FsZSksIHk9UiwgZmlsbD1TaW11bGF0aW9uKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksIHN0YXQ9ImlkZW50aXR5IiwgY29sb3VyPSdibGFjaycpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVItUl9zdGQsIHltYXg9UitSX3N0ZCksIHdpZHRoPS4yLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkrCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZT0iQnVHbiIpK2Nvb3JkX2NhcnRlc2lhbih5bGltPWMoMCwxKSkrdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkrIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSsKICBsYWJzKHg9IkluZGlhbiBSZWdpb25zIix5PSJSZXNpc3RhbmNlIikrCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWw9c3RhdGxhYix5PVIrUl9zdGQrMC4xKSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDEpLHZqdXN0ID0gMCxzaXplPTgpK3RoZW1lKAogIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksCiAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9MjApKQoKCmBgYAoKCmBgYHtyfQojUHV0IHRoZW0gYWxsIGluIG9uZSBwbG90CmdnYXJyYW5nZShtYWluLCBwLCBpLCBjLCBuY29sPTIsIG5yb3c9MiwgY29tbW9uLmxlZ2VuZCA9IFRSVUUsIGxlZ2VuZD0iYm90dG9tIikKZ2dzYXZlKCJmaWd1cmUzLmpwZyIsIHBsb3QgPSBsYXN0X3Bsb3QoKSwgZGV2aWNlID0gTlVMTCwgcGF0aCA9IE5VTEwsc2NhbGUgPSAxLCB3aWR0aCA9IE5BLCBoZWlnaHQgPSBOQSwgdW5pdHMgPSBjKCJpbiIpLGRwaSA9IDYwMCkKYGBgCgoKIyMgUm9idXN0bmVzcwoKVGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIGlzIHVzZWQgdG8gbWFrZSBGaWd1cmUgNCBFLUguCgpgYGB7cn0Kcm9idXN0bmVzczwtcmVhZC5jc3YoIlJvYnVzdG5lc3MuY3N2IikgI3Jlc3VsdHMgb2Ygcm9idXN0bmVzcyBhbmFseXNlcywgc2VlIG1ldGFkYXRhIDIgZm9yIG1vcmUgaW5mbwpzdW1tYXJ5KHJvYnVzdG5lc3MpCiNnZXQgcmlkIG9mIHRoZSByZW1vdmFsIG1vZGVscyB0aGF0IHdlcmUgdGVzdGVkIGJ1dCBub3QgdXNlZApkYXRhMjwtcm9idXN0bmVzcyAlPiUKICAgIGZpbHRlcihtb2RlbCE9IkxUX0JIIiwgbW9kZWwhPSJMVF9ISCIsbW9kZWwhPSJMVF9TSCIsbW9kZWwhPSJUb2xlcmFuY2VfaGlnaCIpCiAgCkdsb2JhbF90b3Q8LWRhdGEyJT4lCiAgZmlsdGVyKG5ldHdvcms9PSJHIixyZW1vdmVkIT0iaG9zdHMiLHJlbW92ZWQhPSJzeW1iaW9udHMiLFI1MF93aG89PSJib3RoIikKR2xvYmFsX3RvdCRyZW1vdmVkPC1mYWN0b3IoR2xvYmFsX3RvdCRyZW1vdmVkLGxldmVscz1jKCJsaW5rcyI9ImxpbmtzIiwibm9kZXMiPSJib3RoIikpCiAgCmdsb2JhbDwtZ2dwbG90KCBHbG9iYWxfdG90LCBhZXMoeD1hcy5mYWN0b3IobW9kZWwpLCB5PW1lYW4sZmlsbD1yZW1vdmVkKSkKZ190b3RhbDwtZ2xvYmFsKwogIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksc3RhdD0iaWRlbnRpdHkiLGNvbG91cj0nYmxhY2snLG1hcHBpbmc9YWVzKGNvbD0icmVkIikpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW4tc3RkLCB5bWF4PW1lYW4rc3RkKSwgd2lkdGg9LjIscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygibGlua3MiID0gIiM3ZmM5N2YiLCAiYm90aCIgPSAiIzk5ZDhjOSIsICJob3N0cyIgPSAiI2E2Y2VlMyIsInN5bWJpb250cyI9IiNmZmZmOTkiKSwgZHJvcCA9IEZBTFNFKSsKICAjeWxpbSgwLDEpKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHM9YygwLDEuMDUpLGV4cGFuZCA9IGMoMCwwKSxicmVha3M9c2VxKDAsIDEsIDAuMSkpKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkrCiAgbGFicyh4PSIiLHk9IlJvYnVzdG5lc3MsIFI1MCIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA3MCwgaGp1c3QgPSAxKSkrCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiUmFuZG9tX2xpbmsiLCJibGVhY2giLCJMVF9CTCIsIkxUX0hMIiwiTFRfU0wiLCJSYW5kb21fbm9kZSIsIlRvbGVyYW5jZV9sb3ciLCJEZWdyZWVfbG93IiwiRGVncmVlX2hpZ2giKSxsYWJlbHM9YygiUmFuZG9tX2xpbmsiPSJSYW5kb20iLCJibGVhY2giPSJCbGVhY2hpbmciLCJUb2xlcmFuY2VfbG93Ij0iU3VzY2VwdGlibGUiLCJUb2xlcmFuY2VfaGlnaCI9IkhpZ2ggVG9sZXJhbmNlIiwiRGVncmVlX2hpZ2giPSAiSGlnaCBEZWdyZWUiLCJEZWdyZWVfbG93Ij0iTG93IERlZ3JlZSIsIlJhbmRvbV9ub2RlIj0iUmFuZG9tIE5vZGUiLCJMVF9CSCI9IkhpZ2ggQXZnLiBMaW5rIFRvbGVyYW5jZSIsIkxUX0JMIj0iU3VzY2VwdGlibGUiLCJMVF9ISCI9IkhpZ2ggSG9zdCBMaW5rIFRvbGVyYW5jZSIsIkxUX0hMIj0iSG9zdCBTdXNjZXB0aWJsZSIsIkxUX1NIIj0iSGlnaCBTeW1iaW9udCBMaW5rIFRvbGVyYW5jZSIsIkxUX1NMIj0iU3ltYmlvbnQgU3VzY2VwdGlibGUiKSkrCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWw9c3RhdGxhYix5PW1lYW4rc3RkKzAuMDUpLHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSx2anVzdCA9IDAsc2l6ZT04KSt0aGVtZSgKICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTIwKSkKClBhY2lmaWNfdG90PC1kYXRhMiU+JQogIGZpbHRlcihuZXR3b3JrPT0iUCIscmVtb3ZlZCE9Imhvc3RzIixyZW1vdmVkIT0ic3ltYmlvbnRzIixSNTBfd2hvPT0iYm90aCIpClBhY2lmaWNfdG90JHJlbW92ZWQ8LWZhY3RvcihQYWNpZmljX3RvdCRyZW1vdmVkLGxldmVscz1jKCJsaW5rcyI9ImxpbmtzIiwibm9kZXMiPSJib3RoIikpCiAgClBhY2lmaWM8LWdncGxvdCggUGFjaWZpY190b3QsIGFlcyh4PWFzLmZhY3Rvcihtb2RlbCksIHk9bWVhbixmaWxsPXJlbW92ZWQpKQpwX3RvdGFsPC1QYWNpZmljKwogIGdlb21fYmFyKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksc3RhdD0iaWRlbnRpdHkiLGNvbG91cj0nYmxhY2snLG1hcHBpbmc9YWVzKGNvbD0icmVkIikpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW4tc3RkLCB5bWF4PW1lYW4rc3RkKSwgd2lkdGg9LjIscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygibGlua3MiID0gIiM3ZmM5N2YiLCAiYm90aCIgPSAiIzk5ZDhjOSIsICJob3N0cyIgPSAiI2E2Y2VlMyIsInN5bWJpb250cyI9IiNmZmZmOTkiKSwgZHJvcCA9IEZBTFNFKSsKICAjeWxpbSgwLDEpKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHM9YygwLDEuMDUpLGV4cGFuZCA9IGMoMCwwKSxicmVha3M9c2VxKDAsIDEsIDAuMSkpKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkrCiAgbGFicyh4PSIiLHk9IiIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA3MCwgaGp1c3QgPSAxKSkrCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiUmFuZG9tX2xpbmsiLCJibGVhY2giLCJMVF9CTCIsIkxUX0hMIiwiTFRfU0wiLCJSYW5kb21fbm9kZSIsIlRvbGVyYW5jZV9sb3ciLCJEZWdyZWVfbG93IiwiRGVncmVlX2hpZ2giKSxsYWJlbHM9YygiUmFuZG9tX2xpbmsiPSJSYW5kb20iLCJibGVhY2giPSJCbGVhY2hpbmciLCJUb2xlcmFuY2VfbG93Ij0iU3VzY2VwdGlibGUiLCJUb2xlcmFuY2VfaGlnaCI9IkhpZ2ggVG9sZXJhbmNlIiwiRGVncmVlX2hpZ2giPSAiSGlnaCBEZWdyZWUiLCJEZWdyZWVfbG93Ij0iTG93IERlZ3JlZSIsIlJhbmRvbV9ub2RlIj0iUmFuZG9tIE5vZGUiLCJMVF9CSCI9IkhpZ2ggQXZnLiBMaW5rIFRvbGVyYW5jZSIsIkxUX0JMIj0iU3VzY2VwdGlibGUiLCJMVF9ISCI9IkhpZ2ggSG9zdCBMaW5rIFRvbGVyYW5jZSIsIkxUX0hMIj0iSG9zdCBTdXNjZXB0aWJsZSIsIkxUX1NIIj0iSGlnaCBTeW1iaW9udCBMaW5rIFRvbGVyYW5jZSIsIkxUX1NMIj0iU3ltYmlvbnQgU3VzY2VwdGlibGUiKSkrCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWw9c3RhdGxhYix5PW1lYW4rc3RkKzAuMDUpLHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSx2anVzdCA9IDAsc2l6ZT04KSt0aGVtZSgKICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLAogIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTIwKSkKCkNhcmliX3RvdDwtZGF0YTIlPiUKICBmaWx0ZXIobmV0d29yaz09IkMiLHJlbW92ZWQhPSJob3N0cyIscmVtb3ZlZCE9InN5bWJpb250cyIsUjUwX3dobz09ImJvdGgiKQpDYXJpYl90b3QkcmVtb3ZlZDwtZmFjdG9yKENhcmliX3RvdCRyZW1vdmVkLGxldmVscz1jKCJsaW5rcyI9ImxpbmtzIiwibm9kZXMiPSJib3RoIikpCgpDYXJpYjwtZ2dwbG90KCBDYXJpYl90b3QsIGFlcyh4PWFzLmZhY3Rvcihtb2RlbCksIHk9bWVhbixmaWxsPXJlbW92ZWQpKQpjX3RvdGFsPC1DYXJpYisKICBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLHN0YXQ9ImlkZW50aXR5Iixjb2xvdXI9J2JsYWNrJyxtYXBwaW5nPWFlcyhjb2w9InJlZCIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1tZWFuLXN0ZCwgeW1heD1tZWFuK3N0ZCksIHdpZHRoPS4yLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImxpbmtzIiA9ICIjN2ZjOTdmIiwgImJvdGgiID0gIiM5OWQ4YzkiLCAiaG9zdHMiID0gIiNhNmNlZTMiLCJzeW1iaW9udHMiPSIjZmZmZjk5IiksIGRyb3AgPSBGQUxTRSkrCiAgI3lsaW0oMCwxKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwxLjA1KSxleHBhbmQgPSBjKDAsMCksYnJlYWtzPXNlcSgwLCAxLCAwLjEpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogIGxhYnMoeD0iIix5PSIiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNzAsIGhqdXN0ID0gMSkpKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlJhbmRvbV9saW5rIiwiYmxlYWNoIiwiTFRfQkwiLCJMVF9ITCIsIkxUX1NMIiwiUmFuZG9tX25vZGUiLCJUb2xlcmFuY2VfbG93IiwiRGVncmVlX2xvdyIsIkRlZ3JlZV9oaWdoIiksbGFiZWxzPWMoIlJhbmRvbV9saW5rIj0iUmFuZG9tIiwiYmxlYWNoIj0iQmxlYWNoaW5nIiwiVG9sZXJhbmNlX2xvdyI9IlN1c2NlcHRpYmxlIiwiVG9sZXJhbmNlX2hpZ2giPSJIaWdoIFRvbGVyYW5jZSIsIkRlZ3JlZV9oaWdoIj0gIkhpZ2ggRGVncmVlIiwiRGVncmVlX2xvdyI9IkxvdyBEZWdyZWUiLCJSYW5kb21fbm9kZSI9IlJhbmRvbSBOb2RlIiwiTFRfQkgiPSJIaWdoIEF2Zy4gTGluayBUb2xlcmFuY2UiLCJMVF9CTCI9IlN1c2NlcHRpYmxlIiwiTFRfSEgiPSJIaWdoIEhvc3QgTGluayBUb2xlcmFuY2UiLCJMVF9ITCI9Ikhvc3QgU3VzY2VwdGlibGUiLCJMVF9TSCI9IkhpZ2ggU3ltYmlvbnQgTGluayBUb2xlcmFuY2UiLCJMVF9TTCI9IlN5bWJpb250IFN1c2NlcHRpYmxlIikpKwogIGdlb21fdGV4dChhZXMoIGxhYmVsPXN0YXRsYWIseT1tZWFuK3N0ZCswLjA1KSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksdmp1c3QgPSAwLHNpemU9OCkrdGhlbWUoCiAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yMCkpCgpJbmRfdG90PC1kYXRhMiU+JQogIGZpbHRlcihuZXR3b3JrPT0iSSIscmVtb3ZlZCE9Imhvc3RzIixyZW1vdmVkIT0ic3ltYmlvbnRzIixSNTBfd2hvPT0iYm90aCIpCkluZF90b3QkcmVtb3ZlZDwtZmFjdG9yKENhcmliX3RvdCRyZW1vdmVkLGxldmVscz1jKCJsaW5rcyI9ImxpbmtzIiwibm9kZXMiPSJib3RoIikpCgpJbmQ8LWdncGxvdCggSW5kX3RvdCwgYWVzKHg9YXMuZmFjdG9yKG1vZGVsKSwgeT1tZWFuLGZpbGw9cmVtb3ZlZCkpCmlfdG90YWw8LUluZCsKICBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLHN0YXQ9ImlkZW50aXR5Iixjb2xvdXI9J2JsYWNrJyxtYXBwaW5nPWFlcyhjb2w9InJlZCIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1tZWFuLXN0ZCwgeW1heD1tZWFuK3N0ZCksIHdpZHRoPS4yLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImxpbmtzIiA9ICIjN2ZjOTdmIiwgImJvdGgiID0gIiM5OWQ4YzkiLCAiaG9zdHMiID0gIiNhNmNlZTMiLCJzeW1iaW9udHMiPSIjZmZmZjk5IiksIGRyb3AgPSBGQUxTRSkrCiAgI3lsaW0oMCwxKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwxLjA1KSxleHBhbmQgPSBjKDAsMCksYnJlYWtzPXNlcSgwLCAxLCAwLjEpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogIGxhYnMoeD0iIix5PSIiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNzAsIGhqdXN0ID0gMSkpKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlJhbmRvbV9saW5rIiwiYmxlYWNoIiwiTFRfQkwiLCJMVF9ITCIsIkxUX1NMIiwiUmFuZG9tX25vZGUiLCJUb2xlcmFuY2VfbG93IiwiRGVncmVlX2xvdyIsIkRlZ3JlZV9oaWdoIiksbGFiZWxzPWMoIlJhbmRvbV9saW5rIj0iUmFuZG9tIiwiYmxlYWNoIj0iQmxlYWNoaW5nIiwiVG9sZXJhbmNlX2xvdyI9IlN1c2NlcHRpYmxlIiwiVG9sZXJhbmNlX2hpZ2giPSJIaWdoIFRvbGVyYW5jZSIsIkRlZ3JlZV9oaWdoIj0gIkhpZ2ggRGVncmVlIiwiRGVncmVlX2xvdyI9IkxvdyBEZWdyZWUiLCJSYW5kb21fbm9kZSI9IlJhbmRvbSBOb2RlIiwiTFRfQkgiPSJIaWdoIEF2Zy4gTGluayBUb2xlcmFuY2UiLCJMVF9CTCI9IlN1c2NlcHRpYmxlIiwiTFRfSEgiPSJIaWdoIEhvc3QgTGluayBUb2xlcmFuY2UiLCJMVF9ITCI9Ikhvc3QgU3VzY2VwdGlibGUiLCJMVF9TSCI9IkhpZ2ggU3ltYmlvbnQgTGluayBUb2xlcmFuY2UiLCJMVF9TTCI9IlN5bWJpb250IFN1c2NlcHRpYmxlIikpKwogIGdlb21fdGV4dChhZXMoIGxhYmVsPXN0YXRsYWIseT1tZWFuK3N0ZCswLjA1KSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksdmp1c3QgPSAwLHNpemU9OCkrdGhlbWUoCiAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yMCkpCgojUHV0IHRoZW0gYWxsIGluIG9uZSBwbG90CmdnYXJyYW5nZShnX3RvdGFsLHBfdG90YWwsaV90b3RhbCxjX3RvdGFsLCBuY29sPTQsIG5yb3c9MSwgY29tbW9uLmxlZ2VuZCA9IEZBTFNFLCBsZWdlbmQ9TlVMTCkKZ2dzYXZlKCJmaWd1cmU0ZXRvZi5qcGciLCBwbG90ID0gbGFzdF9wbG90KCksIGRldmljZSA9IE5VTEwsIHBhdGggPSBOVUxMLHNjYWxlID0gMSwgd2lkdGggPSBOQSwgaGVpZ2h0ID0gTkEsIHVuaXRzID0gYygiaW4iKSxkcGkgPSA2MDApCmBgYAoKVGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIGlzIHVzZWQgdG8gbWFrZSBBcHBlbmRpeCBTMiwgRmlndXJlIFMxIEQtRi4KCmBgYHtyfQpteXBsb3Q8LWZ1bmN0aW9uKGRhdGEyLE4peyAjZGF0YTI9cm9idXN0bmVzcyByZXN1bHRzLCBOPW5ldHdvcmsgdG8gcGxvdAogIGRhdGEyPC1kYXRhMiAlPiUKICAgIGZpbHRlcihtb2RlbCE9IkxUX0JIIiwgbW9kZWwhPSJMVF9ISCIsbW9kZWwhPSJMVF9TSCIsbW9kZWwhPSJUb2xlcmFuY2VfaGlnaCIpCiAgCiAgR2xvYmFsX3RvdDwtZGF0YTIlPiUKICAgIGZpbHRlcihuZXR3b3JrPT1OLHJlbW92ZWQhPSJob3N0cyIscmVtb3ZlZCE9InN5bWJpb250cyIsUjUwX3dobz09ImJvdGgiKQogIEdsb2JhbF90b3QkcmVtb3ZlZDwtZmFjdG9yKEdsb2JhbF90b3QkcmVtb3ZlZCxsZXZlbHM9YygibGlua3MiLCJib3RoIiwiaG9zdHMiLCJzeW1iaW9udHMiKSkKICAKICBnbG9iYWw8LWdncGxvdCggR2xvYmFsX3RvdCwgYWVzKHg9YXMuZmFjdG9yKG1vZGVsKSwgeT1tZWFuLGZpbGw9cmVtb3ZlZCkpCiAgZ190b3RhbDwtZ2xvYmFsKwogICAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSxzdGF0PSJpZGVudGl0eSIsY29sb3VyPSdibGFjaycsbWFwcGluZz1hZXMoY29sPSJyZWQiKSkgKwogICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1tZWFuLXN0ZCwgeW1heD1tZWFuK3N0ZCksIHdpZHRoPS4yLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkrCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygibGlua3MiID0gIiM3ZmM5N2YiLCAiYm90aCIgPSAiIzk5ZDhjOSIsICJob3N0cyIgPSAiI2E2Y2VlMyIsInN5bWJpb250cyI9IiNmZmZmOTkiKSwgCiAgICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpKwogICAgCiAgICAjeWxpbSgwLDEpKwogICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsMS4wNSksZXhwYW5kID0gYygwLDApLGJyZWFrcz1zZXEoMCwgMSwgMC4xKSkrCiAgICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSsKICAgIGxhYnMoeD0iIix5PSJUb3RhbCBSb2J1c3RuZXNzIikrCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDcwLCBoanVzdCA9IDEpKSsKICAgIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlJhbmRvbV9saW5rIiwiYmxlYWNoIiwiTFRfQkwiLCJMVF9ITCIsIkxUX1NMIiwiUmFuZG9tX25vZGUiLCJUb2xlcmFuY2VfbG93IiwiRGVncmVlX2xvdyIsIkRlZ3JlZV9oaWdoIiksCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJSYW5kb21fbGluayI9IlJhbmRvbSIsImJsZWFjaCI9IkJsZWFjaGluZyIsIlRvbGVyYW5jZV9sb3ciPSJTdXNjZXB0aWJsZSIsIlRvbGVyYW5jZV9oaWdoIj0iSGlnaCBUb2xlcmFuY2UiLCJEZWdyZWVfaGlnaCI9ICJIaWdoIERlZ3JlZSIsIkRlZ3JlZV9sb3ciPSJMb3cgRGVncmVlIiwiUmFuZG9tX25vZGUiPSJSYW5kb20gTm9kZSIsIkxUX0JIIj0iSGlnaCBBdmcuIExpbmsgVG9sZXJhbmNlIiwiTFRfQkwiPSJTdXNjZXB0aWJsZSIsIkxUX0hIIj0iSGlnaCBIb3N0IExpbmsgVG9sZXJhbmNlIiwiTFRfSEwiPSJIb3N0IFN1c2NlcHRpYmxlIiwiTFRfU0giPSJIaWdoIFN5bWJpb250IExpbmsgVG9sZXJhbmNlIiwiTFRfU0wiPSJTeW1iaW9udCBTdXNjZXB0aWJsZSIpKSsKICAgIGdlb21fdGV4dChhZXMoIGxhYmVsPXN0YXRsYWIseT1tZWFuK3N0ZCswLjA1KSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksdmp1c3QgPSAwKQogIAogIEdsb2JhbF9oPC1kYXRhMiU+JQogICAgZmlsdGVyKG5ldHdvcms9PU4scmVtb3ZlZCE9Imhvc3RzIixyZW1vdmVkIT0iYm90aCIsUjUwX3dobz09Imhvc3RzIikKICBHbG9iYWxfaCRyZW1vdmVkPC1mYWN0b3IoR2xvYmFsX2gkcmVtb3ZlZCxsZXZlbHM9YygibGlua3MiLCJib3RoIiwiaG9zdHMiLCJzeW1iaW9udHMiKSkKICBnbG9iYWxfaDwtZ2dwbG90KCBHbG9iYWxfaCwgYWVzKHg9YXMuZmFjdG9yKG1vZGVsKSwgeT1tZWFuLGZpbGw9cmVtb3ZlZCkpCiAgZ19ob3N0czwtZ2xvYmFsX2grCiAgICBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLHN0YXQ9ImlkZW50aXR5Iixjb2xvdXI9J2JsYWNrJyxtYXBwaW5nPWFlcyhjb2w9InJlZCIpKSArCiAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPW1lYW4tc3RkLCB5bWF4PW1lYW4rc3RkKSwgd2lkdGg9LjIscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjkpKSsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJsaW5rcyIgPSAiIzdmYzk3ZiIsICJib3RoIiA9ICIjOTlkOGM5IiwgImhvc3RzIiA9ICIjYTZjZWUzIiwic3ltYmlvbnRzIj0iI2ZmZmY5OSIpLCAKICAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkrCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwxLjA1KSxleHBhbmQgPSBjKDAsMCksYnJlYWtzPXNlcSgwLCAxLCAwLjEpKSsKICAgIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpKyAKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogICAgbGFicyh4PSIiLHk9Ikhvc3QgUm9idXN0bmVzcyIpKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA3MCwgaGp1c3QgPSAxKSkrCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJSYW5kb21fbGluayIsImJsZWFjaCIsIkxUX0JMIiwiTFRfSEwiLCJMVF9TTCIsIlJhbmRvbV9ub2RlIiwiVG9sZXJhbmNlX2xvdyIsIkRlZ3JlZV9sb3ciLCJEZWdyZWVfaGlnaCIpLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiUmFuZG9tX2xpbmsiPSJSYW5kb20iLCJibGVhY2giPSJCbGVhY2hpbmciLCJUb2xlcmFuY2VfbG93Ij0iU3VzY2VwdGlibGUiLCJUb2xlcmFuY2VfaGlnaCI9IkhpZ2ggVG9sZXJhbmNlIiwiRGVncmVlX2hpZ2giPSAiSGlnaCBEZWdyZWUiLCJEZWdyZWVfbG93Ij0iTG93IERlZ3JlZSIsIlJhbmRvbV9ub2RlIj0iUmFuZG9tIE5vZGUiLCJMVF9CSCI9IkhpZ2ggQXZnLiBMaW5rIFRvbGVyYW5jZSIsIkxUX0JMIj0iU3VzY2VwdGlibGUiLCJMVF9ISCI9IkhpZ2ggSG9zdCBMaW5rIFRvbGVyYW5jZSIsIkxUX0hMIj0iSG9zdCBTdXNjZXB0aWJsZSIsIkxUX1NIIj0iSGlnaCBTeW1iaW9udCBMaW5rIFRvbGVyYW5jZSIsIkxUX1NMIj0iU3ltYmlvbnQgU3VzY2VwdGlibGUiKSkrCiAgICBnZW9tX3RleHQoYWVzKCBsYWJlbD1zdGF0bGFiLHk9bWVhbitzdGQrMC4wMykscG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLHZqdXN0ID0wKQogIAogIEdsb2JhbF9zPC1kYXRhMiU+JQogICAgZmlsdGVyKG5ldHdvcms9PU4scmVtb3ZlZCE9InN5bWJpb250cyIscmVtb3ZlZCE9ImJvdGgiLFI1MF93aG89PSJzeW1icyIpCiAgR2xvYmFsX3MkcmVtb3ZlZDwtZmFjdG9yKEdsb2JhbF9zJHJlbW92ZWQsbGV2ZWxzPWMoImxpbmtzIiwiYm90aCIsImhvc3RzIiwic3ltYmlvbnRzIikpCiAgZ2xvYmFsX3M8LWdncGxvdCggR2xvYmFsX3MsIGFlcyh4PWFzLmZhY3Rvcihtb2RlbCksIHk9bWVhbixmaWxsPXJlbW92ZWQpKQogIGdfc3ltYnM8LWdsb2JhbF9zKwogICAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSxzdGF0PSJpZGVudGl0eSIsY29sb3VyPSdibGFjaycsbWFwcGluZz1hZXMoY29sPSJyZWQiKSkgKwogICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1tZWFuLXN0ZCwgeW1heD1tZWFuK3N0ZCksIHdpZHRoPS4yLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkrCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygibGlua3MiID0gIiM3ZmM5N2YiLCAiYm90aCIgPSAiIzk5ZDhjOSIsICJob3N0cyIgPSAiI2E2Y2VlMyIsInN5bWJpb250cyI9IiNmZmZmOTkiKSwgCiAgICAgICAgICAgICAgICAgICAgICBkcm9wID0gRkFMU0UpKwogICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsMS4wNSksZXhwYW5kID0gYygwLDApLGJyZWFrcz1zZXEoMCwgMSwgMC4xKSkrCiAgICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSsKICAgIGxhYnMoeD0iIix5PSJTeW1iaW9udCBSb2J1c3RuZXNzIikrCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDcwLCBoanVzdCA9IDEpKSsKICAgIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlJhbmRvbV9saW5rIiwiYmxlYWNoIiwiTFRfQkwiLCJMVF9ITCIsIkxUX1NMIiwiUmFuZG9tX25vZGUiLCJUb2xlcmFuY2VfbG93IiwiRGVncmVlX2xvdyIsIkRlZ3JlZV9oaWdoIiksCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJSYW5kb21fbGluayI9IlJhbmRvbSIsImJsZWFjaCI9IkJsZWFjaGluZyIsIlRvbGVyYW5jZV9sb3ciPSJTdXNjZXB0aWJsZSIsIlRvbGVyYW5jZV9oaWdoIj0iSGlnaCBUb2xlcmFuY2UiLCJEZWdyZWVfaGlnaCI9ICJIaWdoIERlZ3JlZSIsIkRlZ3JlZV9sb3ciPSJMb3cgRGVncmVlIiwiUmFuZG9tX25vZGUiPSJSYW5kb20gTm9kZSIsIkxUX0JIIj0iSGlnaCBBdmcuIExpbmsgVG9sZXJhbmNlIiwiTFRfQkwiPSJTdXNjZXB0aWJsZSIsIkxUX0hIIj0iSGlnaCBIb3N0IExpbmsgVG9sZXJhbmNlIiwiTFRfSEwiPSJIb3N0IFN1c2NlcHRpYmxlIiwiTFRfU0giPSJIaWdoIFN5bWJpb250IExpbmsgVG9sZXJhbmNlIiwiTFRfU0wiPSJTeW1iaW9udCBTdXNjZXB0aWJsZSIpKSsKICAgIGdlb21fdGV4dChhZXMoIGxhYmVsPXN0YXRsYWIseT1tZWFuK3N0ZCswLjAzKSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksdmp1c3QgPTApCiAgCiAgdGhlbWVfc2V0KHRoZW1lX2dyZXkoYmFzZV9zaXplID0gMTQpKSAKICBwPC1nZ2FycmFuZ2UoZ190b3RhbCxnX2hvc3RzLGdfc3ltYnMsIG5jb2w9MywgbnJvdz0xLCBjb21tb24ubGVnZW5kID0gVFJVRSwgbGVnZW5kPSJib3R0b20iKQogIHJldHVybihwKQp9CgpteXBsb3Qocm9idXN0bmVzcywiRyIpCgpgYGAKCiMjIFJhbmRvbWl6YXRpb24gVGVzdHMKClNlZSBBcHBlbmRpeCBTMiBmb3IgZGVzY3JpcHRpb24uIFJhbmRvbWl6YXRpb24gdGVzdHMgYXJlIG9mdGVuIGNhbGxlZCBwZXJtdXRhdGlvbiB0ZXN0cywgdGh1cyBJIHVzZSAicGVybXV0YXRpb24iIHdpdGhpbiB0aGUgY29kZS4KCmBgYHtyfQoKbXlwZXJtdXRhdGlvbl90d29jb21wPC1mdW5jdGlvbihkYXRhLG5ldEEsbmV0QixsZXZlbEEsbGV2ZWxCLG5zaW1zKXsKICAjZ2V0IGRhdGEKICAjbGV2ZWxzKGRhdGEkbmV0X3R5cGUpPC1jKCJoc3JhbmRfZHRlbXAiLCAibmV0X2R0ZW1wIiwgInJhbmRfZHRlbXAiLCJyYmRjX2R0ZW1wIiwgInJibmRjX2R0ZW1wIikKICAjc3BsaXQgZGF0YSBmb3IgdHdvIGxldmVscwogIG5ldDEgPC0gZGF0YSU+JQogICAgZmlsdGVyKG5ldF90eXBlPT1uZXRBKQogIG5ldDIgPC0gZGF0YSU+JQogICAgZmlsdGVyKG5ldF90eXBlPT1uZXRCKQogIHR3b2NvbXBzPC1yYmluZChuZXQxLG5ldDIpCgogICMgaW5pdGlhbGl6ZSB0ZXN0CiAgY29tYmluZWRfcmVzaXN0YW5jZSA8LSBjKG5ldDEkcmVzaXN0YW5jZSxuZXQyJHJlc2lzdGFuY2UpICNjb21iaW5lcyByZXNpc3RhbmNlIHZhbHVlcyBpbnRvIGEgdmVjdG9yCiAgY29tYmluZWRfbGFiZWxzIDwtIGMobmV0MSRuZXRfdHlwZSxuZXQyJG5ldF90eXBlKSNjb21iaW5lcyBuZXR3b3JrIHR5cGUgaW50byBhIHZlY3RvcgogIGRpZmZfb2JzIDwtIG1lYW4obmV0MSRyZXNpc3RhbmNlKSAtIG1lYW4obmV0MiRyZXNpc3RhbmNlKQogIG1vZGVsIDwtIGFub3ZhKGxtKHR3b2NvbXBzJHJlc2lzdGFuY2UgfiB0d29jb21wcyRuZXRfdHlwZSkpIAogIG9idC5GIDwtIG1vZGVsJCJGIHZhbHVlIlsxXSAgICAgIyBPdXIgb2J0YWluZWQgRiAgc3RhdGlzdGljCiAgb2J0LnAgPC0gbW9kZWwkIlByKD5GKSJbMV0KICAKICAjIHBlcm11dGF0aW9uIHRlc3QKICBkaWZmcyA8LSByZXAoTkEsIG5zaW1zKQogIGZzdGF0czwtcmVwKE5BLG5zaW1zKQogIGZvciAoaSBpbiAxOm5zaW1zKSB7CiAgICAjc2h1ZmZsZSB0aGUgbGFiZWxzCiAgICBzaHVmZmxlZF9sYWJlbHMgPC0gc2FtcGxlKGNvbWJpbmVkX2xhYmVscywgcmVwbGFjZSA9IEZBTFNFKQogICAgdHdvY29tcHMkc2h1ZmZsZWRfbGFiZWxzPC1zaHVmZmxlZF9sYWJlbHMKICAgICNzaHVmZmxlIHRoZSByZXNpc3RhbmNlcwogICAgc2h1ZmZsZWRfcmVzaXN0YW5jZTwtc2FtcGxlKGNvbWJpbmVkX3Jlc2lzdGFuY2UsIHJlcGxhY2UgPSBGQUxTRSkKICAgIHR3b2NvbXBzJHNodWZmbGVkX3Jlc2lzdGFuY2U8LXNodWZmbGVkX3Jlc2lzdGFuY2UKICAgICNnZXQgdGhlIGRpZmZlcmVuY2VzIGluIHRoZSBtZWFucyBvZiB0aGUgc2h1ZmZsZWQgZ3JvdXBzCiAgICBkaWZmc1tpXSA8LSBtZWFuKHNodWZmbGVkX3Jlc2lzdGFuY2Vbc2h1ZmZsZWRfbGFiZWxzID09IGxldmVsQV0pIC0gIG1lYW4oc2h1ZmZsZWRfcmVzaXN0YW5jZVtzaHVmZmxlZF9sYWJlbHMgPT0gbGV2ZWxCXSkKICAgICNydW4gYSBuZXcgYW5vdmEKICAgIG5ld21vZGVsIDwtIGFub3ZhKGxtKHR3b2NvbXBzJHNodWZmbGVkX3Jlc2lzdGFuY2UgfiB0d29jb21wcyRzaHVmZmxlZF9sYWJlbHMpKSAKICAgIGZzdGF0c1tpXSA8LSBuZXdtb2RlbCQiRiB2YWx1ZSJbMV0gICAgICMgZ2V0IGEgbmV3IEYgIHN0YXRpc3RpYwogIH0KCiAgI2NhbGN1bGF0ZSB0aGUgdHdvLXNpZGVkIHAtdmFsdWUKICAjIHAtdmFsdWUgPSAobnVtYmVyIG9mIG1vcmUgZXh0cmVtZSBkaWZmZXJlbmNlcyB0aGFuIGRpZmZfb2JzKS9uc2ltcwogIHB2YWxfZGlmZnM8LWxlbmd0aChkaWZmc1thYnMoZGlmZnMpID49IGFicyhkaWZmX29icyldKS9uc2ltcwogIHB2YWxfZnN0YXRkaWZzPC0obGVuZ3RoKGZzdGF0c1thYnMoZnN0YXRzKSA+IGFicyhvYnQuRildKSsxKS8oMStuc2ltcykKICByZXR1cm4oYyhkaWZmX29icyxvYnQucCxvYnQuRixwdmFsX2RpZmZzLHB2YWxfZnN0YXRkaWZzKSkKfQoKcmVzaXN0YW5jZV9wZXJtczwtZnVuY3Rpb24oZmlsZSxuc2ltcyl7CiAgI2dldCBkYXRhCiAgcmVzaXN0X2RhdGE8LXJlYWQuY3N2KGZpbGUpCiAgI3NlbGVjdCBjb2x1bW5zCiAgc2VsZWN0ZGF0YTwtcmVzaXN0X2RhdGElPiUKICAgIHNlbGVjdChoc3JhbmRfZHRlbXAsbmV0X2R0ZW1wLHJhbmRfZHRlbXAscmJkY19kdGVtcCxyYm5kY19kdGVtcCkKICAjZ2V0IGludG8gbG9uZyBmb3JtYXQKICBsb25nZGF0YSA8LSBnYXRoZXIoc2VsZWN0ZGF0YSwga2V5PW5ldF90eXBlLHZhbHVlPXJlc2lzdGFuY2UsZmFjdG9yX2tleSA9IFRSVUUpCiAgI3NldHVwIHN0b3JhZ2UgZm9yIHBlcm11dGF0aW9uIHJlc3VsdHMKICByZXNtYXQ8LW1hdHJpeChOQSxucm93PTAsbmNvbD03KQogIHB2YWxzPC1yZXAoKQogICNydW4gcGVybXV0YXRpb25zCiAgZm9yIChqIGluIDE6KGxlbmd0aChsZXZlbHMobG9uZ2RhdGEkbmV0X3R5cGUpKS0xKSl7CiAgICBuZXRBPC1sZXZlbHMobG9uZ2RhdGEkbmV0X3R5cGUpW2pdCiAgICBmb3IgKGkgaW4gKGorMSk6bGVuZ3RoKGxldmVscyhsb25nZGF0YSRuZXRfdHlwZSkpKXsKICAgICAgbmV0QjwtbGV2ZWxzKGxvbmdkYXRhJG5ldF90eXBlKVtpXQogICAgICBsZXZlbEE8LWoKICAgICAgbGV2ZWxCPC1pCiAgICAgICNwcmludChjKG5ldEEsbmV0QixsZXZlbEEsbGV2ZWxCKSkKICAgICAgcGVybXJlc3VsdHM8LW15cGVybXV0YXRpb25fdHdvY29tcChsb25nZGF0YSxuZXRBLG5ldEIsbGV2ZWxBLGxldmVsQiwxMDAwKQogICAgICAjcHJpbnQocmVzdWx0cykKICAgICAgI3B2YWxzPC1hcHBlbmQocHZhbHMscGVybXJlc3VsdHNbNV0pCiAgICAgIHBlcm1yZXM8LWMocGVybXJlc3VsdHMsbmV0QSxuZXRCKQogICAgICByZXNtYXQ8LXJiaW5kKHJlc21hdCxwZXJtcmVzKQogIH0KfQogIGFsbF9yZXN1bHRzPC1jYmluZChyZXNtYXQscC5hZGp1c3QoYXMubnVtZXJpYyhyZXNtYXRbLDVdKSwiaG9sbSIpKSAjYWRqdXN0IHAgdmFsdWVzIHVzaW5nIHRoZSBob2xtIGNvcnJlY3Rpb24KICByZXN1bHRzPC1hcy5kYXRhLmZyYW1lKGFsbF9yZXN1bHRzKQogIGNvbG5hbWVzKHJlc3VsdHMpPC1jKCJkaWZmX29icyIsIm9idC5wIiwib2J0LkYiLCJwdmFsX2RpZmZzIiwicHZhbF9mc3RhdGRpZnMiLCJuZXQxIiwibmV0MiIsInBfYWRqdXN0X2hvbG0iKQogIHJldHVybihyZXN1bHRzKQp9CgojVEVTVApyZXNpc3RhbmNlX3Blcm1zKCJURVNUX3Jlc2lzdGFuY2VfcGVybXMuY3N2IiwxMDAwKQpgYGAKCiMjIFJvYnVzdG5lc3MgdnMuIENvbm5lY3RhbmNlCgpTZWUgQXBwZW5kaXggUzIgZm9yIGRlc2NyaXB0aW9uLgoKYGBge3J9CiNsb2FkIGRhdGEKcm9idXN0bmVzczwtcmVhZC5jc3YoIlJvYnVzdG5lc3MuY3N2IikKI2NoZWNrIGRpc3RyaWJ1dGlvbiBvZiBjb25uZWN0YW5jZQpwbG90KGRlbnNpdHkoKGxvZyhyb2J1c3RuZXNzJGNvbm5lY3RhbmNlKSkpKSAjSXQncyB3b25reS4KCiNtYWtlIGl0IGVhc3kgdG8gcGxvdCByZW1vdmFsIG1vZGVsIG9mIGNob2ljZSB2cyBjb25uZWN0YW5jZSB3aXRoIGEgbGluZWFyIGZpdApteV9SQ2xpbnJlZ19wbG90PC1mdW5jdGlvbihjaG9pY2UpewogIGRhdGE8LXJvYnVzdG5lc3MgJT4lCiAgICBmaWx0ZXIobW9kZWwhPSJMVF9CSCIsIG1vZGVsIT0iTFRfSEgiLG1vZGVsIT0iTFRfU0giLG1vZGVsIT0iVG9sZXJhbmNlX2hpZ2giLFI1MF93aG89PSJib3RoIixtb2RlbD09Y2hvaWNlKQoKICBwPC1nZ3Bsb3RSZWdyZXNzaW9uKGxtKG1lYW4gfiBjb25uZWN0YW5jZSwgZGF0YSA9IGRhdGEpLGNob2ljZSkKICBwK2dlb21fcG9pbnQoeT1kYXRhJG1lYW4seD1kYXRhJGNvbm5lY3RhbmNlLGFlcyhjb2xvcj1kYXRhJGdyb3VwKSxzaXplPTYpCiAgCn0KCiNydW4gYSBLZW5kYWxsJ3MgY29lZmZpY2llbnQgb2YgcmFuayBjb3JyZWxhdGlvbiB0ZXN0IG9uIHJlbW92YWwgbW9kZWwgb2YgY2hvaWNlCm15X2NvcnRlc3Q8LWZ1bmN0aW9uKGNob2ljZSl7CiAgZGF0YTwtcm9idXN0bmVzcyAlPiUKICAgIGZpbHRlcihtb2RlbCE9IkxUX0JIIiwgbW9kZWwhPSJMVF9ISCIsbW9kZWwhPSJMVF9TSCIsbW9kZWwhPSJUb2xlcmFuY2VfaGlnaCIsUjUwX3dobz09ImJvdGgiLG1vZGVsPT1jaG9pY2UpCiAgY3Q8LWNvci50ZXN0KGRhdGEkbWVhbixkYXRhJGNvbm5lY3RhbmNlLG1ldGhvZD0ia2VuZGFsbCIpCiAgcmV0dXJuKGN0KQp9CiNydW4gZm9yIGRpZmZlcmVudCByZW1vdmFsIG1vZGVscyAKbXlfUkNsaW5yZWdfcGxvdCgiYmxlYWNoIikKbXlfY29ydGVzdCgiYmxlYWNoIikgCm15X1JDbGlucmVnX3Bsb3QoIlJhbmRvbV9saW5rIikKbXlfY29ydGVzdCgiUmFuZG9tX2xpbmsiKQpteV9SQ2xpbnJlZ19wbG90KCJMVF9CTCIpCm15X2NvcnRlc3QoIkxUX0JMIikKbXlfUkNsaW5yZWdfcGxvdCgiTFRfSEwiKQpteV9jb3J0ZXN0KCJMVF9ITCIpCm15X1JDbGlucmVnX3Bsb3QoIkxUX1NMIikKbXlfY29ydGVzdCgiTFRfU0wiKQpteV9SQ2xpbnJlZ19wbG90KCJEZWdyZWVfaGlnaCIpCm15X2NvcnRlc3QoIkRlZ3JlZV9oaWdoIikKbXlfUkNsaW5yZWdfcGxvdCgiRGVncmVlX2xvdyIpCm15X2NvcnRlc3QoIkRlZ3JlZV9sb3ciKQpteV9SQ2xpbnJlZ19wbG90KCJSYW5kb21fbm9kZSIpCm15X2NvcnRlc3QoIlJhbmRvbV9ub2RlIikKbXlfUkNsaW5yZWdfcGxvdCgiVG9sZXJhbmNlX2xvdyIpCm15X2NvcnRlc3QoIlRvbGVyYW5jZV9sb3ciKQoKYGBgCgojIyBTeW1iaW9udCBub2RlIHRoZXJtYWwgdG9sZXJhbmNlczogcGlja2luZyBtaXNzaW5nIHRvbGVyYW5jZXMKCkNvZGUgZm9yIEFwcGVuZGl4IFMxLCBGaWd1cmUgUzE6IEZyZXF1ZW5jeSBkaXN0cmlidXRpb24gb2YgU3ltYmlvZGluaXVtIHRoZXJtYWwgdG9sZXJhbmNlIHNjb3JlcyBhZGFwdGVkIGZyb20gU3dhaW4gZXQgYWwuICgyMDE3KTsgZGlzdHJpYnV0aW9uIGlzIGNvbG9yZWQgYnkgdG9sZXJhbmNlIHJhbmdlLCByZWQgaXMgaGlnaGx5IHN1c2NlcHRpYmxlLCBvcmFuZ2UgaXMgbWVkaXVtIHRvbGVyYW5jZSwgYW5kIHllbGxvdyBpcyBoaWdoIHRvbGVyYW5jZS4gU3dhaW4gZXQgYWwuICgyMDE3KSBwcm92aWRlcyBhIGZyYW1ld29yayBmb3IgYSBjb25zZW5zdXMgb2YgU3ltYmlvZGluaXVtIHRoZXJtb3RvbGVyYW5jZSByYW5rcyBkZXZlbG9wZWQgZnJvbSByYW5rLWFnZ3JlZ2F0aW9uIG1ldGhvZHMuIFRoZWlyIHJhbmtpbmcgc2NoZW1lIG9yZGVycyBTeW1iaW9kaW5pdW0gcGh5bG90eXBlcyBmcm9tIDAtMTAwLCBidXQgdGhlIHJhbmsgdmFsdWVzIGFyZSBub3QgaW5kaWNhdGl2ZSBvZiB0b3RhbCBtYWduaXR1ZGUgZGlmZmVyZW5jZXMgaW4gdGhlcm1vdG9sZXJhbmNlLiBUbyBkZXRlcm1pbmUgdG9sZXJhbmNlcyBvZiB0aGUgdW5saXN0ZWQgc3ltYmlvbnQgdHlwZXMgaW4gb3VyIG5ldHdvcmssIHJhbmsgdmFsdWVzIHdlcmUgcmFuZG9tbHkgZHJhd24gZnJvbSB0aGUgaGlnaCwgbWVkaXVtLCBhbmQgbG93IHRoZXJtYWwgdG9sZXJhbmNlIGZyZXF1ZW5jeSBkaXN0cmlidXRpb25zIGluIHRoZSByZWxhdGl2ZSBwcm9wb3J0aW9ucyBvZiB0aGUgY2xhZGVzIHJlcHJlc2VudGVkIGluIHRob3NlIGRpc3RyaWJ1dGlvbnMuIFRodXMsIGZvciBlYWNoIHNpbXVsYXRpb24gb2YgZWl0aGVyIHRoZSBibGVhY2hpbmcgb3IgZGlmZmVyZW50IHJlbW92YWwgbW9kZWxzIGRlc2NyaWJlZCBiZWxvdywgdGhlIHN5bWJpb250IHRvbGVyYW5jZXMgdmFyaWVkIHdpdGhpbiBhIHNldCBkaXN0cmlidXRpb24gKEZpZ3VyZSAxRCkuCmBgYHtyfQojIyMgRXhwbG9yaW5nIGRhdGEgZnJvbSBTd2FpbiBldCBhbCAyMDE2YSAjIyMjCmRhdGE8LXJlYWQuY3N2KCJTd2FpblN5bWJzUi5jc3YiKQojZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbiAtLT4gaW5zZXQgZnJvbSBmaWd1cmUgMSBmcm9tIHBhcGVyCmJpbnM9c2VxKDAsMTAwLGJ5PTIpCiNzcGxpdCB0aGUgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbiBpbnRvIDMgc3Vic2V0cyBkZWZpbmVkIGJ5IHN3YWluIGV0IGFsIDE2CmxvdyA8LSBkYXRhW3doaWNoKGRhdGEkU2NvcmVSX2s8PTE3KSxdCmhpZ2ggPC0gZGF0YVt3aGljaChkYXRhJFNjb3JlUl9rPj0zMyksXQptaWRkbGU8LSBkYXRhW3doaWNoKGRhdGEkU2NvcmVSX2s+MTcgJiBkYXRhJFNjb3JlUl9rPDMzKSxdCiNIaWdoIGhpc3QKaGlzdChoaWdoJFNjb3JlUl9rLCBicmVha3M9YmlucywgY29sPSJ5ZWxsb3ciLCB5bGltPWMoMCwxMiksIHhsYWI9InRoZXJtb3RvbGVyYW5jZSBzY29yZSIsIG1haW49IkZyZXF1ZW5jeSBEaXN0cmlidXRpb25zIG9mIFRoZXJtb3RvbGVyYW5jZSBTY29yZXMiKQojbWlkZGxlIGhpc3QKaGlzdChtaWRkbGUkU2NvcmVSX2ssIGJyZWFrcz1iaW5zLCBjb2w9Im9yYW5nZSIsIGFkZD1UKQojbG93IGhpc3QKaGlzdChsb3ckU2NvcmVSX2ssIGJyZWFrcz1iaW5zLCBjb2w9InJlZCIsIGFkZD1UKQoKYGBgCkNvZGUgZm9yIGZpdHRpbmcgdGhlIGFib3ZlIHRoZXJtYWwgdG9lbHJhbmNlIGRpc3RyaWJ1dGlvbnMgZGlzdHJpYnV0aW9ucwpgYGB7cn0KIyMjIEZpdCB0aGUgVGhlcm1vdG9sZXJhbmNlIERpc3RyaWJ1dGlvbnMgIyMjIwojZmlyc3QgbmVlZCB0aGUgbWl4dG9vbHMgcGFja2FnZQppZighKCJtaXh0b29scyIgJWluJSBpbnN0YWxsZWQucGFja2FnZXMoKSkpe2luc3RhbGwucGFja2FnZXMoIm1peHRvb2xzIil9CmxpYnJhcnkoIm1peHRvb2xzIikKI1VzZSB0aGUgZXhwZWN0YXRpb24gTWF4aW1pemF0aW9uIChFTSkgQXBwcm9hY2gKZW0gPC0gbm9ybWFsbWl4RU0oZGF0YSRTY29yZVJfaywgYXJidmFyID0gVFJVRSxlcHNpbG9uID0gMWUtMDMsIGsgPSAzKQojIEVzdGltYXRlZCBtZWFucwplbSRtdQojIEVzdGltYXRlZCBzdGFuZGFyZCBkZXZpYXRpb25zCmVtJHNpZ21hCiMjI1JFU1VMVFMKIz4gZW0kbXUKI1sxXSAgNy45ODMwMjkgMjkuNDA4NTcwIDUxLjkwMDMzOQojPiBlbSRzaWdtYQojWzFdICAyLjcxMTQ4MCAgOS41MDA1ODcgMTguMDA2NjI2CgojZG8gMTAwMDAgc2ltdWxhdGlvbnMgIyMjIwpydW5zIDwtIDEwMDAwCnNpbXMubG93IDwtIHJub3JtKHJ1bnMsbWVhbj03Ljk4MzAyOSxzZD0yLjcxMTQ4MCkKc2ltcy5taWRkbGUgPC1ybm9ybShydW5zLG1lYW49MjkuNDA4NTcwLHNkPTkuNTAwNTg3KQpzaW1zLmhpZ2g8LXJub3JtKHJ1bnMsbWVhbj01MS45MDAzMzksc2Q9MTguMDA2NjI2KQojSGlnaCBoaXN0Cmhpc3Qoc2ltcy5oaWdoLCBjb2w9InllbGxvdyIpCiNtaWRkbGUgaGlzdApoaXN0KHNpbXMubWlkZGxlLCBjb2w9Im9yYW5nZSIsIGFkZD1UKQojbG93IGhpc3QKaGlzdChzaW1zLmxvdywgY29sPSJyZWQiLCBhZGQ9VCkKCmBgYApDb2RlIGZvciBzZXR0aW5nIHVwIGZvciB0b2VscmFuY2UgZnVuY3Rpb24KYGBge3J9CiNWQUxVRVMgVEhBVCBBUkUgTkVFREVEICMjIyMgCiMjVGhlc2UgYXJlIGp1c3QgdGhlIG51bWJlcnMgb2Ygc3ltYnMgZnJvbSBlYWNoIGNsYWRlIGluIGVhY2ggZnJlcSBsZXZlbCBmcm9tIFN3YWluCnN3YWluX0E8LTgKc3dhaW5fQjwtOApzd2Fpbl9DPC03MQpzd2Fpbl9EPC0xOQpzd2Fpbl9FPC0xCnN3YWluX0Y8LTMKCmxvd19BPC0xCm1pZGRsZV9BPC0zCmhpZ2hfQTwtNApwcm9iX2xvd19BPC1sb3dfQS9zd2Fpbl9BCnByb2JfbWlkZGxlX0E8LW1pZGRsZV9BL3N3YWluX0EKcHJvYl9oaWdoX0E8LWhpZ2hfQS9zd2Fpbl9BCgpsb3dfQjwtMwptaWRkbGVfQjwtNApoaWdoX0I8LTEKcHJvYl9sb3dfQjwtbG93X0Ivc3dhaW5fQgpwcm9iX21pZGRsZV9CPC1taWRkbGVfQi9zd2Fpbl9CCnByb2JfaGlnaF9CPC1oaWdoX0Ivc3dhaW5fQgoKbG93X0M8LTI0Cm1pZGRsZV9DPC0xOQpoaWdoX0M8LTI4CnByb2JfbG93X0M8LWxvd19DL3N3YWluX0MKcHJvYl9taWRkbGVfQzwtbWlkZGxlX0Mvc3dhaW5fQwpwcm9iX2hpZ2hfQzwtaGlnaF9DL3N3YWluX0MKCmxvd19EPC0zCm1pZGRsZV9EPC00CmhpZ2hfRDwtMTIKcHJvYl9sb3dfRDwtbG93X0Qvc3dhaW5fRApwcm9iX21pZGRsZV9EPC1taWRkbGVfRC9zd2Fpbl9ECnByb2JfaGlnaF9EPC1oaWdoX0Qvc3dhaW5fRAoKbG93X0U8LTEKcHJvYl9sb3dfRTwtMQpwcm9iX21pZGRsZV9FPC0wCnByb2JfaGlnaF9FPC0wCgpoaWdoX0Y8LTMKcHJvYl9sb3dfRjwtMApwcm9iX21pZGRsZV9GPC0wCnByb2JfaGlnaF9GPC0xCiNPSyBzbyB0aGVzZSBhcmUgdGhlIG51bWJlciBvZiBzeW1icyBpbiBlYWNoIGNsYWRlIHRoYXQgZG9udCBoYXZlIHRvbGVyYW5jZXMgCm5ldF9BPC02Cm5ldF9CPC0xMwpuZXRfQzwtMTYwCm5ldF9EPC02Cm5ldF9FPC0wCm5ldF9GPC0wCmBgYAoKRnVuY3Rpb24gZm9yIGdldHRpbmcgdGhlIHRvbGVyYW5jZXMKYGBge3J9CmdldF90b2xzPC1mdW5jdGlvbihzaXplLGxvd3Byb2IsbWlkcHJvYixoaWdocHJvYixydW5zLHNpbXMubG93LHNpbXMubWlkZGxlLHNpbXMuaGlnaCl7CiAgI21ha2UgYSBzYW1wbGUgZGlzdHJpYnV0aW9uIHdoZXJlIDEgY29ycmVzcG9uZHMgdG8gdGhlIGxvdyB0aGVybWFsdG9sZXJhbmNlLAogICMgMiBpcyB0aGUgbWVkaXVtIGFuZCAzIGlzIGhpZ2guIDE6MyBhcmUgcHV0IGludG8gdGhlIHNhbXBsZSBkaXN0cmlidXRpb24gCiAgI2Jhc2VkIG9uIHRoZSBwcm9iYWJpbGl0aWVzIGluIHRoZSBmdW5jdGlvbiBpbnB1dCB0aGF0IGFyZSBjbGFkZSBzcGVjaWZpYwogIHNhbXBsZWRpc3RyPC1zYW1wbGUoeCA9IDE6Mywgc2l6ZSA9IHNpemUsIHByb2IgPSBjKGxvd3Byb2IsIG1pZHByb2IsIGhpZ2hwcm9iKSwgcmVwbGFjZT1UUlVFKQogIHRvbGVyYW5jZTwtbnVtZXJpYyhsZW5ndGg9c2l6ZSkKICBmb3IgKGkgaW4gMTpzaXplKSB7ICNmb3IgZWFjaCBudW1iZXIgaW4gdGhlIHNhbXBsZWRpc3RyIGRvOgogICAgaWYgKHNhbXBsZWRpc3RyW2ldPT0xKXsKICAgICAgdG9sZXJhbmNlW2ldPC1zYW1wbGUoeD1zaW1zLmxvdyxzaXplPTEpICNwdWxsIGZyb20gbG93CiAgICB9CiAgICBlbHNlIGlmIChzYW1wbGVkaXN0cltpXT09Mil7ICNwdWxsIGZyb20gbWlkZGxlCiAgICAgIHRvbGVyYW5jZVtpXTwtc2FtcGxlKHg9c2ltcy5taWRkbGUsc2l6ZT0xKQogICAgfQogICAgZWxzZSAKICAgICAgdG9sZXJhbmNlW2ldPC1zYW1wbGUoeD1zaW1zLmhpZ2gsc2l6ZT0xKSAjcHVsbCBmcm9tIGhpZ2gKICB9CiAgdG9sZXJhbmNlPC1zcXJ0KHRvbGVyYW5jZSkvMTAgI3Rha2UgdGhlIHNxcnQgYmVjYXVzZSBzd2FpbidzIHRvbGVyYW5jZXMgYXJlIG5vdCBpbmRpY2F0aXZlIG9mIG1hZ25pdHVkZSBhbmQgdGhlbiBkaXZpZGUgYnkgMTAgdG8gZ2V0IGEgbnVtYmVyIGZyb20gMC0xCiAgcmV0dXJuKHRvbGVyYW5jZSkKfQpgYGAKCk1ha2UgMTAwIHNpbXVsYXRpb25zIHdvcnRoIG9mIHRvbGVyYW5jZSBmaWxlcwpgYGB7cn0KdHJpYWxzPTEgI2FjdHVhbGx5IGRpZCAxMDAsIGJ1dCBkb24ndCB3YW50IHRvIG1ha2UgYSB0b24gb2YgbmV3IGZpbGVzLCBzbyBoZXJlIGlzIDEgZXhhbXBsZSBmaWxlLgpsc3Q9c2VxKDE6dHJpYWxzKQpmb3IoaSBpbiBzZXFfYWxvbmcobHN0KSl7CiAgQ3RvbHM8LWdldF90b2xzKG5ldF9DLHByb2JfbG93X0MscHJvYl9taWRkbGVfQyxwcm9iX2hpZ2hfQywxMDAwMCxzaW1zLmxvdyxzaW1zLm1pZGRsZSxzaW1zLmhpZ2gpCiAgQXRvbHM8LWdldF90b2xzKG5ldF9BLHByb2JfbG93X0EscHJvYl9taWRkbGVfQSxwcm9iX2hpZ2hfQSwxMDAwMCxzaW1zLmxvdyxzaW1zLm1pZGRsZSxzaW1zLmhpZ2gpCiAgQnRvbHM8LWdldF90b2xzKG5ldF9CLHByb2JfbG93X0IscHJvYl9taWRkbGVfQixwcm9iX2hpZ2hfQiwxMDAwMCxzaW1zLmxvdyxzaW1zLm1pZGRsZSxzaW1zLmhpZ2gpCiAgRHRvbHM8LWdldF90b2xzKG5ldF9ELHByb2JfbG93X0QscHJvYl9taWRkbGVfRCxwcm9iX2hpZ2hfRCwxMDAwMCxzaW1zLmxvdyxzaW1zLm1pZGRsZSxzaW1zLmhpZ2gpCiAgQ3RvbHM8LWFzLmRhdGEuZnJhbWUoQ3RvbHMpCiAgQXRvbHM8LWFzLmRhdGEuZnJhbWUoQXRvbHMpCiAgQnRvbHM8LWFzLmRhdGEuZnJhbWUoQnRvbHMpCiAgRHRvbHM8LWFzLmRhdGEuZnJhbWUoRHRvbHMpCiAgY29sbmFtZXMoQ3RvbHMpIDwtIGMoInRvbGVyYW5jZSIpCiAgY29sbmFtZXMoQnRvbHMpIDwtIGMoInRvbGVyYW5jZSIpCiAgY29sbmFtZXMoRHRvbHMpIDwtIGMoInRvbGVyYW5jZSIpCiAgY29sbmFtZXMoQXRvbHMpIDwtIGMoInRvbGVyYW5jZSIpCiAgbmV3c2NvcmVzPC1yYmluZChBdG9scyxCdG9scyxDdG9scyxEdG9scykKICBuYW1lPC1wYXN0ZSgndHJpYWwnLGksIi5jc3YiLHNlcD0iIikKICAKICB3cml0ZS5jc3YobmV3c2NvcmVzLG5hbWUscm93Lm5hbWVzPUZBTFNFKQp9CgpgYGAKCk5vdyBmb3IgdGhlIHNodWZmbGVkIHRvbGVyYW5jZXM6CmBgYHtyfQojIE5vdyBnZXQgdGhlIHRvbGVyYW5lcyBmb3IgdGhlIFNodWZmbGVkIFN5bWJpb250cy8gU2h1ZmZsZWQgUmFuZG9tIG51bGwgbW9kZWwgIyMjIwojZm9yIHRoZSByYW5kb20gc2V0IG9mIHRvbGVyYW5jZXMgd2hlcmUgdGhleSBhcmUgYWxsIHB1bGxlZCBlcXVhbGx5IGZyb20gdGhlIDMgZGlzdHJpYnV0aW9ucwpydW5zPTEwMDAwCnNpbXMubG93IDwtIHJub3JtKHJ1bnMsbWVhbj03Ljk4MzAyOSxzZD0yLjcxMTQ4MCkKc2ltcy5sb3c8LXN1YnNldChzaW1zLmxvdyxzaW1zLmxvdz49MCkKc2ltcy5taWRkbGUgPC1ybm9ybShydW5zLG1lYW49MjkuNDA4NTcwLHNkPTkuNTAwNTg3KQpzaW1zLm1pZGRsZTwtc3Vic2V0KHNpbXMubWlkZGxlLHNpbXMubWlkZGxlPj0wKQpzaW1zLmhpZ2g8LXJub3JtKHJ1bnMsbWVhbj01MS45MDAzMzksc2Q9MTguMDA2NjI2KSAKc2ltcy5oaWdoPC1zdWJzZXQoc2ltcy5oaWdoLHNpbXMuaGlnaDw9MTAwKQpzaW1zLmhpZ2g8LXN1YnNldChzaW1zLmhpZ2gsc2ltcy5oaWdoPj0wKQoKI3NvIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gZG9lcyB3aGF0IHRoZSBvbGQgb25lIGRpZCBidXQgYWxzbyBzcGVjaWZpZXMKI2lmIHVzaW5nIHByb2JhYmlsaWVzIGRldGVybWluZWQgZnJvbSBkYXRhIG9yIGlmIHB1bGxpbmcgYWxsIHZhbHVlcyBmcm9tIAojdGhlIGRpc3RyaWJ1dGlvbnMgd2l0aCB0aGUgc2FtZSBwcm9iYWJpbGl0eSAoMS8zKQphbGx0aGVkYXRhPC1mdW5jdGlvbihwcm9iYWJpbGl0eSx0cmlhbHMsc2ltcy5sb3csc2ltcy5taWRkbGUsc2ltcy5oaWdoLG5ldF9BLG5ldF9CLG5ldF9DLG5ldF9EKXsKICBpZiAocHJvYmFiaWxpdHk9PTEpewogICAgc3dhaW5fQTwtOAogICAgc3dhaW5fQjwtOAogICAgc3dhaW5fQzwtNzEKICAgIHN3YWluX0Q8LTE5CiAgICBzd2Fpbl9FPC0xCiAgICBzd2Fpbl9GPC0zCiAgICAKICAgIGxvd19BPC0xCiAgICBtaWRkbGVfQTwtMwogICAgaGlnaF9BPC00CiAgICBwcm9iX2xvd19BPC1sb3dfQS9zd2Fpbl9BCiAgICBwcm9iX21pZGRsZV9BPC1taWRkbGVfQS9zd2Fpbl9BCiAgICBwcm9iX2hpZ2hfQTwtaGlnaF9BL3N3YWluX0EKICAgIAogICAgbG93X0I8LTMKICAgIG1pZGRsZV9CPC00CiAgICBoaWdoX0I8LTEKICAgIHByb2JfbG93X0I8LWxvd19CL3N3YWluX0IKICAgIHByb2JfbWlkZGxlX0I8LW1pZGRsZV9CL3N3YWluX0IKICAgIHByb2JfaGlnaF9CPC1oaWdoX0Ivc3dhaW5fQgogICAgCiAgICBsb3dfQzwtMjQKICAgIG1pZGRsZV9DPC0xOQogICAgaGlnaF9DPC0yOAogICAgcHJvYl9sb3dfQzwtbG93X0Mvc3dhaW5fQwogICAgcHJvYl9taWRkbGVfQzwtbWlkZGxlX0Mvc3dhaW5fQwogICAgcHJvYl9oaWdoX0M8LWhpZ2hfQy9zd2Fpbl9DCiAgICAKICAgIGxvd19EPC0zCiAgICBtaWRkbGVfRDwtNAogICAgaGlnaF9EPC0xMgogICAgcHJvYl9sb3dfRDwtbG93X0Qvc3dhaW5fRAogICAgcHJvYl9taWRkbGVfRDwtbWlkZGxlX0Qvc3dhaW5fRAogICAgcHJvYl9oaWdoX0Q8LWhpZ2hfRC9zd2Fpbl9ECiAgICAKICAgIGxvd19FPC0xCiAgICBwcm9iX2xvd19FPC0xCiAgICBwcm9iX21pZGRsZV9FPC0wCiAgICBwcm9iX2hpZ2hfRTwtMAogICAgCiAgICBoaWdoX0Y8LTMKICAgIHByb2JfbG93X0Y8LTAKICAgIHByb2JfbWlkZGxlX0Y8LTAKICAgIHByb2JfaGlnaF9GPC0xCiAgICAKICB9CiAgZWxzZQogICAgcHJvYl9sb3dfQz1wcm9iX21pZGRsZV9DPXByb2JfaGlnaF9DPXByb2JfbG93X0E9cHJvYl9taWRkbGVfQT1wcm9iX2hpZ2hfQT1wcm9iX2xvd19CPXByb2JfbWlkZGxlX0I9cHJvYl9oaWdoX0I9cHJvYl9sb3dfRD1wcm9iX21pZGRsZV9EPXByb2JfaGlnaF9EPSgxLzMpCiAgCiAgI25ldF9BPC04CiAgI25ldF9CPC0xOAogICNuZXRfQzwtMTc3CiAgI25ldF9EPC03CiAgI25ldF9FPC0wCiAgI25ldF9GPC0wCiAgbHN0PXNlcSgxOnRyaWFscykKICBmb3IoaSBpbiBzZXFfYWxvbmcobHN0KSl7CiAgICBDdG9sczwtZ2V0X3RvbHMobmV0X0MscHJvYl9sb3dfQyxwcm9iX21pZGRsZV9DLHByb2JfaGlnaF9DLDEwMDAwLHNpbXMubG93LHNpbXMubWlkZGxlLHNpbXMuaGlnaCkKICAgIEF0b2xzPC1nZXRfdG9scyhuZXRfQSxwcm9iX2xvd19BLHByb2JfbWlkZGxlX0EscHJvYl9oaWdoX0EsMTAwMDAsc2ltcy5sb3csc2ltcy5taWRkbGUsc2ltcy5oaWdoKQogICAgQnRvbHM8LWdldF90b2xzKG5ldF9CLHByb2JfbG93X0IscHJvYl9taWRkbGVfQixwcm9iX2hpZ2hfQiwxMDAwMCxzaW1zLmxvdyxzaW1zLm1pZGRsZSxzaW1zLmhpZ2gpCiAgICBEdG9sczwtZ2V0X3RvbHMobmV0X0QscHJvYl9sb3dfRCxwcm9iX21pZGRsZV9ELHByb2JfaGlnaF9ELDEwMDAwLHNpbXMubG93LHNpbXMubWlkZGxlLHNpbXMuaGlnaCkKICAgIEN0b2xzPC1hcy5kYXRhLmZyYW1lKEN0b2xzKQogICAgQXRvbHM8LWFzLmRhdGEuZnJhbWUoQXRvbHMpCiAgICBCdG9sczwtYXMuZGF0YS5mcmFtZShCdG9scykKICAgIER0b2xzPC1hcy5kYXRhLmZyYW1lKER0b2xzKQogICAgY29sbmFtZXMoQ3RvbHMpIDwtIGMoInRvbGVyYW5jZSIpCiAgICBjb2xuYW1lcyhCdG9scykgPC0gYygidG9sZXJhbmNlIikKICAgIGNvbG5hbWVzKER0b2xzKSA8LSBjKCJ0b2xlcmFuY2UiKQogICAgY29sbmFtZXMoQXRvbHMpIDwtIGMoInRvbGVyYW5jZSIpCiAgICBuZXdzY29yZXM8LXJiaW5kKEF0b2xzLEJ0b2xzLEN0b2xzLER0b2xzKQogICAgbmFtZTwtcGFzdGUoJ3J0cmlhbCcsaSwiLmNzdiIsc2VwPSIiKQogICAgCiAgICB3cml0ZS5jc3YobmV3c2NvcmVzLG5hbWUscm93Lm5hbWVzPUZBTFNFKQogIH0KfQojc2l6ZSBvZiB0aGUgY2xhZGVzIGluIHRoZSBuZXR3b3JrCm5ldF9BPC0xMApuZXRfQjwtMjAKbmV0X0M8LTIxMQpuZXRfRDwtOQphbGx0aGVkYXRhKDAsMSxzaW1zLmxvdyxzaW1zLm1pZGRsZSxzaW1zLmhpZ2gsbmV0X0EsbmV0X0IsbmV0X0MsbmV0X0QpCmBgYAoKIyBSZXZpc2VkIEZpZ3VyZXMKCkZpZ3VyZSA0LCBub3cgd2l0aG91dCB0aGUgZGVncmVlIHJlbW92YWwgbW9kZWxzCmBgYHtyfQojLGZpZy5oZWlnaHQ9MixmaWcud2lkdGg9NC41fQpyb2J1c3RuZXNzPC1yZWFkLmNzdigiUm9idXN0bmVzcy5jc3YiKSAjcmVzdWx0cyBvZiByb2J1c3RuZXNzIGFuYWx5c2VzLCBzZWUgbWV0YWRhdGEgMiBmb3IgbW9yZSBpbmZvCnN1bW1hcnkocm9idXN0bmVzcykKI2dldCByaWQgb2YgdGhlIHJlbW92YWwgbW9kZWxzIHRoYXQgd2VyZSB0ZXN0ZWQgYnV0IG5vdCB1c2VkCmRhdGEyPC1yb2J1c3RuZXNzICU+JQogICAgZmlsdGVyKG1vZGVsIT0iTFRfQkgiLCBtb2RlbCE9IkxUX0hIIixtb2RlbCE9IkxUX1NIIixtb2RlbCE9IlRvbGVyYW5jZV9oaWdoIixtb2RlbCE9IkRlZ3JlZV9oaWdoIixtb2RlbCE9IkRlZ3JlZV9sb3ciKSU+JQogIGRyb3BsZXZlbHMoKQoKbGV2ZWxzKGRhdGEyJG1vZGVsKQpHbG9iYWxfdG90PC1kYXRhMiU+JQogIGZpbHRlcihuZXR3b3JrPT0iRyIscmVtb3ZlZCE9Imhvc3RzIixyZW1vdmVkIT0ic3ltYmlvbnRzIixSNTBfd2hvPT0iYm90aCIpCkdsb2JhbF90b3QkcmVtb3ZlZDwtZmFjdG9yKEdsb2JhbF90b3QkcmVtb3ZlZCxsZXZlbHM9YygibGlua3MiPSJsaW5rcyIsIm5vZGVzIj0iYm90aCIpKQogIApnbG9iYWw8LWdncGxvdCggR2xvYmFsX3RvdCwgYWVzKHg9YXMuZmFjdG9yKG1vZGVsKSwgeT1tZWFuLGZpbGw9cmVtb3ZlZCkpCmdfdG90YWw8LWdsb2JhbCsKICBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLHN0YXQ9ImlkZW50aXR5Iixjb2xvdXI9J2JsYWNrJyxtYXBwaW5nPWFlcyhjb2w9InJlZCIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1tZWFuLXN0ZCwgeW1heD1tZWFuK3N0ZCksIHdpZHRoPS4yLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImxpbmtzIiA9ICIjN2ZjOTdmIiwgImJvdGgiID0gIiM5OWQ4YzkiLCAiaG9zdHMiID0gIiNhNmNlZTMiLCJzeW1iaW9udHMiPSIjZmZmZjk5IiksIGRyb3AgPSBGQUxTRSkrCiAgI3lsaW0oMCwxKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwxLjA1KSxleHBhbmQgPSBjKDAsMCksYnJlYWtzPXNlcSgwLCAxLCAwLjEpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogIGxhYnMoeD0iIix5PSJSb2J1c3RuZXNzLCBSNTAiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNzAsIGhqdXN0ID0gMSkpKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlJhbmRvbV9saW5rIiwiYmxlYWNoIiwiTFRfQkwiLCJMVF9ITCIsIkxUX1NMIiwiUmFuZG9tX25vZGUiLCJUb2xlcmFuY2VfbG93IiksbGFiZWxzPWMoIlJhbmRvbV9saW5rIj0iUmFuZG9tIiwiYmxlYWNoIj0iQmxlYWNoaW5nIiwiVG9sZXJhbmNlX2xvdyI9IlN1c2NlcHRpYmxlIiwiVG9sZXJhbmNlX2hpZ2giPSJIaWdoIFRvbGVyYW5jZSIsIkRlZ3JlZV9oaWdoIj0gIkhpZ2ggRGVncmVlIiwiRGVncmVlX2xvdyI9IkxvdyBEZWdyZWUiLCJSYW5kb21fbm9kZSI9IlJhbmRvbSBOb2RlIiwiTFRfQkgiPSJIaWdoIEF2Zy4gTGluayBUb2xlcmFuY2UiLCJMVF9CTCI9IlN1c2NlcHRpYmxlIiwiTFRfSEgiPSJIaWdoIEhvc3QgTGluayBUb2xlcmFuY2UiLCJMVF9ITCI9Ikhvc3QgU3VzY2VwdGlibGUiLCJMVF9TSCI9IkhpZ2ggU3ltYmlvbnQgTGluayBUb2xlcmFuY2UiLCJMVF9TTCI9IlN5bWJpb250IFN1c2NlcHRpYmxlIikpKwogIGdlb21fdGV4dChhZXMoIGxhYmVsPXN0YXRsYWIseT1tZWFuK3N0ZCswLjA1KSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksdmp1c3QgPSAwLHNpemU9OCkrdGhlbWUoCiAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yMCkpCgpQYWNpZmljX3RvdDwtZGF0YTIlPiUKICBmaWx0ZXIobmV0d29yaz09IlAiLHJlbW92ZWQhPSJob3N0cyIscmVtb3ZlZCE9InN5bWJpb250cyIsUjUwX3dobz09ImJvdGgiKQpQYWNpZmljX3RvdCRyZW1vdmVkPC1mYWN0b3IoUGFjaWZpY190b3QkcmVtb3ZlZCxsZXZlbHM9YygibGlua3MiPSJsaW5rcyIsIm5vZGVzIj0iYm90aCIpKQogIApQYWNpZmljPC1nZ3Bsb3QoIFBhY2lmaWNfdG90LCBhZXMoeD1hcy5mYWN0b3IobW9kZWwpLCB5PW1lYW4sZmlsbD1yZW1vdmVkKSkKcF90b3RhbDwtUGFjaWZpYysKICBnZW9tX2Jhcihwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLHN0YXQ9ImlkZW50aXR5Iixjb2xvdXI9J2JsYWNrJyxtYXBwaW5nPWFlcyhjb2w9InJlZCIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1tZWFuLXN0ZCwgeW1heD1tZWFuK3N0ZCksIHdpZHRoPS4yLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImxpbmtzIiA9ICIjN2ZjOTdmIiwgImJvdGgiID0gIiM5OWQ4YzkiLCAiaG9zdHMiID0gIiNhNmNlZTMiLCJzeW1iaW9udHMiPSIjZmZmZjk5IiksIGRyb3AgPSBGQUxTRSkrCiAgI3lsaW0oMCwxKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwxLjA1KSxleHBhbmQgPSBjKDAsMCksYnJlYWtzPXNlcSgwLCAxLCAwLjEpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpKwogIGxhYnMoeD0iIix5PSIiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNzAsIGhqdXN0ID0gMSkpKwogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlJhbmRvbV9saW5rIiwiYmxlYWNoIiwiTFRfQkwiLCJMVF9ITCIsIkxUX1NMIiwiUmFuZG9tX25vZGUiLCJUb2xlcmFuY2VfbG93IiksbGFiZWxzPWMoIlJhbmRvbV9saW5rIj0iUmFuZG9tIiwiYmxlYWNoIj0iQmxlYWNoaW5nIiwiVG9sZXJhbmNlX2xvdyI9IlN1c2NlcHRpYmxlIiwiVG9sZXJhbmNlX2hpZ2giPSJIaWdoIFRvbGVyYW5jZSIsIkRlZ3JlZV9oaWdoIj0gIkhpZ2ggRGVncmVlIiwiRGVncmVlX2xvdyI9IkxvdyBEZWdyZWUiLCJSYW5kb21fbm9kZSI9IlJhbmRvbSBOb2RlIiwiTFRfQkgiPSJIaWdoIEF2Zy4gTGluayBUb2xlcmFuY2UiLCJMVF9CTCI9IlN1c2NlcHRpYmxlIiwiTFRfSEgiPSJIaWdoIEhvc3QgTGluayBUb2xlcmFuY2UiLCJMVF9ITCI9Ikhvc3QgU3VzY2VwdGlibGUiLCJMVF9TSCI9IkhpZ2ggU3ltYmlvbnQgTGluayBUb2xlcmFuY2UiLCJMVF9TTCI9IlN5bWJpb250IFN1c2NlcHRpYmxlIikpKwogIGdlb21fdGV4dChhZXMoIGxhYmVsPXN0YXRsYWIseT1tZWFuK3N0ZCswLjA1KSxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksdmp1c3QgPSAwLHNpemU9OCkrdGhlbWUoCiAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI0KSwKICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yMCkpCgpDYXJpYl90b3Q8LWRhdGEyJT4lCiAgZmlsdGVyKG5ldHdvcms9PSJDIixyZW1vdmVkIT0iaG9zdHMiLHJlbW92ZWQhPSJzeW1iaW9udHMiLFI1MF93aG89PSJib3RoIikKQ2FyaWJfdG90JHJlbW92ZWQ8LWZhY3RvcihDYXJpYl90b3QkcmVtb3ZlZCxsZXZlbHM9YygibGlua3MiPSJsaW5rcyIsIm5vZGVzIj0iYm90aCIpKQoKQ2FyaWI8LWdncGxvdCggQ2FyaWJfdG90LCBhZXMoeD1hcy5mYWN0b3IobW9kZWwpLCB5PW1lYW4sZmlsbD1yZW1vdmVkKSkKY190b3RhbDwtQ2FyaWIrCiAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSxzdGF0PSJpZGVudGl0eSIsY29sb3VyPSdibGFjaycsbWFwcGluZz1hZXMoY29sPSJyZWQiKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bWVhbi1zdGQsIHltYXg9bWVhbitzdGQpLCB3aWR0aD0uMixwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJsaW5rcyIgPSAiIzdmYzk3ZiIsICJib3RoIiA9ICIjOTlkOGM5IiwgImhvc3RzIiA9ICIjYTZjZWUzIiwic3ltYmlvbnRzIj0iI2ZmZmY5OSIpLCBkcm9wID0gRkFMU0UpKwogICN5bGltKDAsMSkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsMS4wNSksZXhwYW5kID0gYygwLDApLGJyZWFrcz1zZXEoMCwgMSwgMC4xKSkrCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkrIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkscGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSsKICBsYWJzKHg9IiIseT0iIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIixheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDcwLCBoanVzdCA9IDEpKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJSYW5kb21fbGluayIsImJsZWFjaCIsIkxUX0JMIiwiTFRfSEwiLCJMVF9TTCIsIlJhbmRvbV9ub2RlIiwiVG9sZXJhbmNlX2xvdyIpLGxhYmVscz1jKCJSYW5kb21fbGluayI9IlJhbmRvbSIsImJsZWFjaCI9IkJsZWFjaGluZyIsIlRvbGVyYW5jZV9sb3ciPSJTdXNjZXB0aWJsZSIsIlRvbGVyYW5jZV9oaWdoIj0iSGlnaCBUb2xlcmFuY2UiLCJEZWdyZWVfaGlnaCI9ICJIaWdoIERlZ3JlZSIsIkRlZ3JlZV9sb3ciPSJMb3cgRGVncmVlIiwiUmFuZG9tX25vZGUiPSJSYW5kb20gTm9kZSIsIkxUX0JIIj0iSGlnaCBBdmcuIExpbmsgVG9sZXJhbmNlIiwiTFRfQkwiPSJTdXNjZXB0aWJsZSIsIkxUX0hIIj0iSGlnaCBIb3N0IExpbmsgVG9sZXJhbmNlIiwiTFRfSEwiPSJIb3N0IFN1c2NlcHRpYmxlIiwiTFRfU0giPSJIaWdoIFN5bWJpb250IExpbmsgVG9sZXJhbmNlIiwiTFRfU0wiPSJTeW1iaW9udCBTdXNjZXB0aWJsZSIpKSsKICBnZW9tX3RleHQoYWVzKCBsYWJlbD1zdGF0bGFiLHk9bWVhbitzdGQrMC4wNSkscG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLHZqdXN0ID0gMCxzaXplPTgpK3RoZW1lKAogIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksCiAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9MjApKQoKSW5kX3RvdDwtZGF0YTIlPiUKICBmaWx0ZXIobmV0d29yaz09IkkiLHJlbW92ZWQhPSJob3N0cyIscmVtb3ZlZCE9InN5bWJpb250cyIsUjUwX3dobz09ImJvdGgiKQpJbmRfdG90JHJlbW92ZWQ8LWZhY3RvcihDYXJpYl90b3QkcmVtb3ZlZCxsZXZlbHM9YygibGlua3MiPSJsaW5rcyIsIm5vZGVzIj0iYm90aCIpKQoKSW5kPC1nZ3Bsb3QoIEluZF90b3QsIGFlcyh4PWFzLmZhY3Rvcihtb2RlbCksIHk9bWVhbixmaWxsPXJlbW92ZWQpKQppX3RvdGFsPC1JbmQrCiAgZ2VvbV9iYXIocG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSxzdGF0PSJpZGVudGl0eSIsY29sb3VyPSdibGFjaycsbWFwcGluZz1hZXMoY29sPSJyZWQiKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bWVhbi1zdGQsIHltYXg9bWVhbitzdGQpLCB3aWR0aD0uMixwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJsaW5rcyIgPSAiIzdmYzk3ZiIsICJib3RoIiA9ICIjOTlkOGM5IiwgImhvc3RzIiA9ICIjYTZjZWUzIiwic3ltYmlvbnRzIj0iI2ZmZmY5OSIpLCBkcm9wID0gRkFMU0UpKwogICN5bGltKDAsMSkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsMS4wNSksZXhwYW5kID0gYygwLDApLGJyZWFrcz1zZXEoMCwgMSwgMC4xKSkrCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkrIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkscGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSsKICBsYWJzKHg9IiIseT0iIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIixheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDcwLCBoanVzdCA9IDEpKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJSYW5kb21fbGluayIsImJsZWFjaCIsIkxUX0JMIiwiTFRfSEwiLCJMVF9TTCIsIlJhbmRvbV9ub2RlIiwiVG9sZXJhbmNlX2xvdyIpLGxhYmVscz1jKCJSYW5kb21fbGluayI9IlJhbmRvbSIsImJsZWFjaCI9IkJsZWFjaGluZyIsIlRvbGVyYW5jZV9sb3ciPSJTdXNjZXB0aWJsZSIsIlRvbGVyYW5jZV9oaWdoIj0iSGlnaCBUb2xlcmFuY2UiLCJEZWdyZWVfaGlnaCI9ICJIaWdoIERlZ3JlZSIsIkRlZ3JlZV9sb3ciPSJMb3cgRGVncmVlIiwiUmFuZG9tX25vZGUiPSJSYW5kb20gTm9kZSIsIkxUX0JIIj0iSGlnaCBBdmcuIExpbmsgVG9sZXJhbmNlIiwiTFRfQkwiPSJTdXNjZXB0aWJsZSIsIkxUX0hIIj0iSGlnaCBIb3N0IExpbmsgVG9sZXJhbmNlIiwiTFRfSEwiPSJIb3N0IFN1c2NlcHRpYmxlIiwiTFRfU0giPSJIaWdoIFN5bWJpb250IExpbmsgVG9sZXJhbmNlIiwiTFRfU0wiPSJTeW1iaW9udCBTdXNjZXB0aWJsZSIpKSsKICBnZW9tX3RleHQoYWVzKCBsYWJlbD1zdGF0bGFiLHk9bWVhbitzdGQrMC4wNSkscG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLHZqdXN0ID0gMCxzaXplPTgpK3RoZW1lKAogIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksCiAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksCiAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9MjApKQoKI1B1dCB0aGVtIGFsbCBpbiBvbmUgcGxvdApnZ2FycmFuZ2UoZ190b3RhbCxwX3RvdGFsLGlfdG90YWwsY190b3RhbCwgbmNvbD00LCBucm93PTEsIGNvbW1vbi5sZWdlbmQgPSBGQUxTRSwgbGVnZW5kPU5VTEwpCmdnc2F2ZSgiZmlndXJlNGV0b2YuanBnIiwgcGxvdCA9IGxhc3RfcGxvdCgpLCBkZXZpY2UgPSBOVUxMLCBwYXRoID0gTlVMTCxzY2FsZSA9IDEsIHdpZHRoID0gTkEsIGhlaWdodCA9IE5BLCB1bml0cyA9IGMoImluIiksZHBpID0gNjAwKQpgYGAKCgo=